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;
}
}
}