统一监听jwttoken的校验

package com.k5003.gatewayzuul.config;

import com.k5003.gatewayzuul.service.GatewayService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.stream.Collectors;

/**

  • 统一监听jwttoken的校验

  • king 2020.05.03
    */
    @Component
    public class JwtTokenFilter implements GlobalFilter, Ordered {

     @Autowired
     GatewayService gtewayService;
    
     //公钥
     private static final String PUBLIC_KEY = "publickey.txt";
    
     //跳过验证地址 登录等
     private String[] skipAuthUrls = {"/auth/auth/userlogin","/auth/auth/v2/api-docs","/users/users/v2/api-docs","/qiniu/qiniu/v2/api-docs"};
    
     @Override
     public int getOrder() {
         return -1;
     }
    
     /**
      * 过滤器
      * @param exchange
      * @param chain
      * @return
      */
     @Override
     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
         String url = exchange.getRequest().getURI().getPath();
         System.out.println(url);
         String token = exchange.getRequest().getHeaders().getFirst("Authorization");
         System.out.println(token);
         if (null != skipAuthUrls && Arrays.asList(skipAuthUrls).contains(url)) {
             return chain.filter(exchange);
         }
         if (StringUtils.isBlank(token)) {
                 return returnAuthFail(exchange, "请先登陆");
         } else {
             //判断是否存在cookie
             String tokenFromCookie = gtewayService.getTokenFromCookie(exchange);
             if(StringUtils.isEmpty(tokenFromCookie)){
                 //拒绝访问
                 //return returnAuthFail(exchange, "登录超时,请重新登录");
             }
             //从header中取jwt
             String jwtFromHeader = gtewayService.getJwtFromHeader(exchange);
             if(StringUtils.isEmpty(jwtFromHeader)){
                 //拒绝访问
                 return returnAuthFail(exchange, "异常访问,请重新登录");
             }
             //从redis取出jwt的过期时间
             //long expire = gtewayService.getExpire(tokenFromCookie);
             //if(expire<0){
                 //拒绝访问
                 //return returnAuthFail(exchange, "登录超时,请重新登录");
             //}
             //根据公钥校验token
             Boolean isjwts=jwrVerify(token);
             if(!isjwts){
                 //拒绝访问
                 return returnAuthFail(exchange, "登录异常,请重新登录");
             }
             return chain.filter(exchange);
         }
     }
    
     /**
      * 返回校验失败
      *
      * @param exchange
      * @return
      */
     private Mono<Void> returnAuthFail(ServerWebExchange exchange,String message) {
         ServerHttpResponse serverHttpResponse = exchange.getResponse();
         serverHttpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
         String resultData = "{\"status\":\"-1\",\"msg\":"+message+"}";
         byte[] bytes = resultData.getBytes(StandardCharsets.UTF_8);
         DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
         return exchange.getResponse().writeWith(Flux.just(buffer));
     }
    

    /**

    • 校验jwt的合法性
    • @param jwtString
    • @return
      */
      private Boolean jwrVerify(String jwtString){
      Boolean jwtver=true;
      String publickey=getPubKey();
      //校验jwt令牌
      try{
      Jwt jwt = JwtHelper.decodeAndVerify(jwtString.replace(“Bearer “,””), new RsaVerifier(publickey));
      } catch (Exception e) {
      jwtver=false;
      }
      return jwtver;
      }

    /**

    • 获取公钥字符
    • @return
      */
      private String getPubKey() {
      Resource resource = new ClassPathResource(PUBLIC_KEY);
      try {
      InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream());
      BufferedReader br = new BufferedReader(inputStreamReader);
      return br.lines().collect(Collectors.joining("\n"));
      } catch (IOException ioe) {
      return null;
      }
      }

}