1.通过认证授权模块进行登录
在这里我们默认登录都是可以正常获取token令牌的,也就是都是登录成功的
2.微服务网关(SpringGateway)
代码语言:javascript复制在该微服务中我们通过拦截器链接请求,通过该请求是排除过滤的 uri 地址(例如:登录请求/auth/login),则放行该请求,否则则进行token认证,在这里我们有2种认证方式: 2.1 网关统一认证授权(本次不介绍该模式) 该模式需要使用redis进行缓存所有的认证路径和所有路径所需要的角色权限信息,最后在网关中统一鉴权,其他微服务不进行鉴权处理。
2.2 网关检验Token是否合法,在其他需要鉴权的微服务中注入【公共拦截器】进行统一的鉴权处理 1.网关中的具体代码操作
@Component
public class AuthFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
// 排除过滤的 uri 地址
@Autowired
private IgnoreWhiteProperties ignoreWhite;
@Autowired
private RedisService redisService;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpRequest.Builder mutate = request.mutate();
String url = request.getURI().getPath();
// 跳过不需要验证的路径
if (StringUtils.matches(url, ignoreWhite.getWhites())) {
return chain.filter(exchange);
}
//检验Token是否合法
// 获取token令牌,具体获取方法不做介绍
String token = getToken(request);
// 1.判断token是否为空
if (StringUtils.isEmpty(token)) {
return unauthorizedResponse(exchange, "令牌不能为空");
}
// 解析token令牌,过期或无效则返回null
Claims claims = JwtUtils.parseToken(token);
//判断令牌是否有些
if (claims == null) {
return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
}
//TODO 其他处理
//TODO 设置解析的用户信息到请求头中
return chain.filter(exchange.mutate().request(mutate.build()).build());
}
private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg) {
log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED);
}
}
代码语言:javascript复制2.公共模块中的拦截器操作
public class HeaderInterceptor implements AsyncHandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
//获取网关中传过来的参数
String userKey = ServletUtils.getHeader(request, SecurityConstants.USER_KEY);
SecurityContextHolder.setUserId(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USER_ID));
SecurityContextHolder.setUserName(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USERNAME));
SecurityContextHolder.setUserKey(ServletUtils.getHeader(request, SecurityConstants.USER_KEY));
//调用方法,获取令牌
String token = SecurityUtils.getToken();
//解析token令牌
if (StringUtils.isNotEmpty(token)) {
//进行令牌获取用户信息
LoginUser loginUser = AuthUtil.getLoginUser(token);
if (StringUtils.isNotNull(loginUser)) {
AuthUtil.verifyLoginUserExpire(loginUser);
//把用户信息注入服务上下文中
SecurityContextHolder.set(SecurityConstants.LOGIN_USER, loginUser);
}
}
return true;
}
到此方法二中的微服务认证授权的处理方法已完成