You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
7.2 KiB
176 lines
7.2 KiB
5 years ago
|
package com.epmet.auth;
|
||
|
|
||
|
import com.epmet.commons.tools.constant.AppClientConstant;
|
||
|
import com.epmet.commons.tools.constant.Constant;
|
||
|
import com.epmet.commons.tools.exception.EpmetErrorCode;
|
||
|
import com.epmet.commons.tools.exception.RenException;
|
||
|
import com.epmet.commons.tools.security.dto.BaseTokenDto;
|
||
|
import com.epmet.commons.tools.security.dto.GovTokenDto;
|
||
|
import com.epmet.commons.tools.security.dto.TokenDto;
|
||
|
import com.epmet.commons.tools.utils.CpUserDetailRedis;
|
||
|
import com.epmet.commons.tools.utils.Result;
|
||
|
import com.epmet.jwt.JwtTokenUtils;
|
||
|
import io.jsonwebtoken.Claims;
|
||
|
import org.apache.commons.lang3.StringUtils;
|
||
|
import org.slf4j.Logger;
|
||
|
import org.slf4j.LoggerFactory;
|
||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||
|
import org.springframework.http.HttpHeaders;
|
||
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||
|
import org.springframework.stereotype.Component;
|
||
|
import org.springframework.web.server.ServerWebExchange;
|
||
|
import reactor.core.publisher.Mono;
|
||
|
|
||
|
/**
|
||
|
* 内部认证处理器
|
||
|
*/
|
||
|
@Component
|
||
|
public class InternalAuthProcessor extends AuthProcessor {
|
||
|
|
||
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
||
|
|
||
|
@Autowired
|
||
|
private JwtTokenUtils jwtTokenUtils;
|
||
|
|
||
|
@Autowired
|
||
|
private CpUserDetailRedis cpUserDetailRedis;
|
||
|
|
||
|
@Override
|
||
|
public Mono<Void> auth(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||
|
ServerHttpRequest request = exchange.getRequest();
|
||
|
String requestUri = request.getPath().pathWithinApplication().value();
|
||
|
|
||
|
logger.info("CpAuthGatewayFilterFactory当前requestUri=[" + requestUri + "]CpAuthGatewayFilterFactory拦截成功");
|
||
|
String token = getTokenFromRequest(request);
|
||
|
//BaseTokenDto baseTokenDto = StringUtils.isNotBlank(token) ? getBaseTokenDto(token, jwtTokenUtils) : null;
|
||
|
BaseTokenDto baseTokenDto;
|
||
|
if(StringUtils.isNotBlank(token)){
|
||
|
try{
|
||
|
baseTokenDto = getBaseTokenDto(token, jwtTokenUtils);
|
||
|
}catch(RenException e){
|
||
|
return response(exchange,new Result<>().error(e.getCode(),e.getMsg()));
|
||
|
}
|
||
|
}else{
|
||
|
baseTokenDto = null;
|
||
|
}
|
||
|
|
||
|
String customerId = "";
|
||
|
|
||
|
if (baseTokenDto != null) {
|
||
|
if (AppClientConstant.APP_RESI.equals(baseTokenDto.getApp())) {
|
||
|
// 居民端
|
||
|
TokenDto resiTokenDto = getLoginUserInfoByToken(token, jwtTokenUtils, TokenDto.class);
|
||
|
if (resiTokenDto != null) {
|
||
|
customerId = resiTokenDto.getCustomerId();
|
||
|
baseTokenDto = resiTokenDto;
|
||
|
}
|
||
|
} else if (AppClientConstant.APP_GOV.equals(baseTokenDto.getApp())) {
|
||
|
// 政府端
|
||
|
GovTokenDto govTokenDto = getLoginUserInfoByToken(token, jwtTokenUtils, GovTokenDto.class);
|
||
|
if (govTokenDto != null) {
|
||
|
customerId = govTokenDto.getCustomerId();
|
||
|
baseTokenDto = govTokenDto;
|
||
|
}
|
||
|
} else if(AppClientConstant.APP_OPER.equals(baseTokenDto.getApp())){
|
||
|
//运营端
|
||
|
TokenDto resiTokenDto = getLoginUserInfoByToken(token, jwtTokenUtils, TokenDto.class);
|
||
|
if (resiTokenDto != null) {
|
||
|
customerId = resiTokenDto.getCustomerId();
|
||
|
baseTokenDto = resiTokenDto;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 校验token
|
||
|
if (StringUtils.isBlank(token)) {
|
||
|
return response(exchange,new Result<>().error(EpmetErrorCode.ERR10005.getCode(),EpmetErrorCode.ERR10005.getMsg()));
|
||
|
}
|
||
|
try {
|
||
|
validateTokenDto(baseTokenDto, token);
|
||
|
} catch (RenException e) {
|
||
|
return response(exchange,new Result<>().error(e.getCode(),e.getMsg()));
|
||
|
}
|
||
|
|
||
|
// 添加header
|
||
|
if (baseTokenDto != null) {
|
||
|
String redisKey = baseTokenDto.getApp() + "-" + baseTokenDto.getClient() + "-" + baseTokenDto.getUserId();
|
||
|
logger.info("redisKey=" + redisKey);
|
||
|
exchange.getRequest().mutate()
|
||
|
.header(Constant.APP_USER_KEY, redisKey)
|
||
|
.header(AppClientConstant.APP,baseTokenDto.getApp())
|
||
|
.header(AppClientConstant.CLIENT,baseTokenDto.getClient())
|
||
|
.header(AppClientConstant.USER_ID,baseTokenDto.getUserId());
|
||
|
|
||
|
if (StringUtils.equals(baseTokenDto.getApp(), "gov")) {//工作端
|
||
|
if(StringUtils.isNotBlank(customerId)){
|
||
|
exchange.getRequest().mutate().header(AppClientConstant.CUSTOMER_ID, customerId);
|
||
|
}
|
||
|
} else if (StringUtils.equals(baseTokenDto.getApp(), "public")) {//公众号端
|
||
|
exchange.getRequest().mutate().header(AppClientConstant.CUSTOMER_ID, customerId);
|
||
|
}
|
||
|
ServerHttpRequest build = exchange.getRequest().mutate().build();
|
||
|
return chain.filter(exchange.mutate().request(build).build());
|
||
|
}
|
||
|
|
||
|
return chain.filter(exchange);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 从请求中获取token
|
||
|
* @param request
|
||
|
* @return
|
||
|
*/
|
||
|
private String getTokenFromRequest(ServerHttpRequest request) {
|
||
|
HttpHeaders headers = request.getHeaders();
|
||
|
String token = headers.getFirst(Constant.AUTHORIZATION_HEADER);
|
||
|
if (StringUtils.isBlank(token)) {
|
||
|
token = headers.getFirst(Constant.TOKEN_HEADER);
|
||
|
}
|
||
|
if (StringUtils.isBlank(token)) {
|
||
|
token = request.getQueryParams().getFirst(Constant.AUTHORIZATION_HEADER);
|
||
|
}
|
||
|
return token;
|
||
|
}
|
||
|
|
||
|
private BaseTokenDto getBaseTokenDto(String token, JwtTokenUtils jwtTokenUtils) {
|
||
|
//是否过期
|
||
|
Claims claims = jwtTokenUtils.getClaimByToken(token);
|
||
|
if (claims == null || jwtTokenUtils.isTokenExpired(claims.getExpiration())) {
|
||
|
return null;
|
||
|
}
|
||
|
//获取用户ID
|
||
|
String app = (String) claims.get("app");
|
||
|
String client = (String) claims.get("client");
|
||
|
String userId = (String) claims.get("userId");
|
||
|
return new BaseTokenDto(app, client, userId, token);
|
||
|
}
|
||
|
|
||
|
private <T> T getLoginUserInfoByToken(String token, JwtTokenUtils jwtTokenUtils, Class<T> clz) {
|
||
|
BaseTokenDto baseTokenDto = getBaseTokenDto(token, jwtTokenUtils);
|
||
|
//查询Redis
|
||
|
return cpUserDetailRedis.get(baseTokenDto.getApp(), baseTokenDto.getClient(), baseTokenDto.getUserId(), clz);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 校验Token是否异常
|
||
|
* @param tokenDto
|
||
|
* @param tokenStr
|
||
|
*/
|
||
|
private void validateTokenDto(BaseTokenDto tokenDto, String tokenStr) {
|
||
|
if (null == tokenDto) {
|
||
|
//说明登录状态时效(超时)
|
||
|
throw new RenException(EpmetErrorCode.ERR10006.getCode());
|
||
|
}else{
|
||
|
//Redis中存在数据,取出token,进行比对
|
||
|
if(StringUtils.equals(tokenDto.getToken(),tokenStr)){
|
||
|
//用户携带token与Redis中一致
|
||
|
|
||
|
}else{
|
||
|
//用户携带token与Redis中不一致,说明当前用户此次会话失效,提示重新登陆
|
||
|
throw new RenException(EpmetErrorCode.ERR10007.getCode());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|