diff --git a/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/UserTokenService.java b/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/UserTokenService.java index 0f17a30..d52ff73 100644 --- a/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/UserTokenService.java +++ b/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/UserTokenService.java @@ -34,7 +34,7 @@ public interface UserTokenService { String getToken(HttpServletRequest request); /** - * 获取登录用户名 + * 根据令牌token, 获取登录用户名 * * @param token * @return 登录用户名 diff --git a/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/filter/JwtAuthenticationTokenFilter.java b/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/filter/JwtAuthenticationTokenFilter.java index e22fc25..b3961db 100644 --- a/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/filter/JwtAuthenticationTokenFilter.java +++ b/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/filter/JwtAuthenticationTokenFilter.java @@ -33,7 +33,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { @Autowired UserTokenService userTokenService; //@Autowired - //UserDetailsService userDetailsService; + // UserDetailsService userDetailsService; @Autowired AuthenticationResult authenticationResult; @@ -49,14 +49,14 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse try { UserDetails userDetails = userTokenService.getUserDetails(token); - //userDetailsService.loadUserByUsername(userName); - if (userDetails != null && SecurityContextHolder.getContext().getAuthentication() == null) { + // 认证成功吧 Authentication 对象 setAuthenticated(true), 然存到 SecurityContext 中 + // 认证失败则清空 SecurityContext 然后交给下一个 Filter 处理 UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authenticationToken); - //设置登录 + // 设置登录 JwtUserDetails jwtUserDetails = (JwtUserDetails) userDetails; AuthenticationUser authenticationUser = AuthenticationUserFactory.getByJwtUser(jwtUserDetails); @@ -70,7 +70,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse filterChain.doFilter(request, response); - //清除登录信息 + // 清除登录信息 UserContextUtil.clear(); } } diff --git a/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/jwt/JwtUserDetailsService.java b/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/jwt/JwtUserDetailsService.java index 0774e1b..43ca1b7 100644 --- a/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/jwt/JwtUserDetailsService.java +++ b/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/jwt/JwtUserDetailsService.java @@ -8,6 +8,21 @@ */ public interface JwtUserDetailsService { + /** + * 验证令牌的有效性 + * 通过验证salt的有效性,来达到认证用户令牌的有效性 + * 这里的有效性不是令牌有效时间的有效性,可以在一下几个场景使用: + * - 1. 用户注销,重置下 salt 使 令牌失效 + * - 2. 多地登陆,控制登录账号数量 + * + * @param userDetails + * @param salt + * @return + */ + default boolean verifySalt(UserDetails userDetails, String salt) { + return true; + } + /** * 通过用户Id获取用户详情 * @@ -15,4 +30,6 @@ public interface JwtUserDetailsService { * @return */ UserDetails loadUserByUserId(Long userId); + + } diff --git a/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/jwt/JwtUserTokenService.java b/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/jwt/JwtUserTokenService.java index ac02c18..e7c6a3e 100644 --- a/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/jwt/JwtUserTokenService.java +++ b/security-spring-boot-starter/src/main/java/com/admin4j/framework/security/jwt/JwtUserTokenService.java @@ -101,7 +101,14 @@ public UserDetails getUserDetails(String token) { .build(); verifier.verify(token); - return jwtUserDetailsService.loadUserByUserId(userId); + // 可以验证下 salt 是否有效,用来验证令牌是否已注销 + UserDetails userDetails = jwtUserDetailsService.loadUserByUserId(userId); + if (userDetails != null) { + if (!jwtUserDetailsService.verifySalt(userDetails, jwt.getClaim(FILED_SALT).asString())) { + return null; + } + } + return userDetails; } private String generateSecret(String salt) {