Java 通过基于角色的授权使用JWT 背景
我正在使用SpringSecurity开发一个web应用程序,并首次尝试使用JSONWeb令牌进行身份验证。应用程序应根据用户角色限制对某些URI的访问。它应该提供密码更改选项,并允许Java 通过基于角色的授权使用JWT 背景,java,rest,spring-security,authorization,jwt,Java,Rest,Spring Security,Authorization,Jwt,我正在使用SpringSecurity开发一个web应用程序,并首次尝试使用JSONWeb令牌进行身份验证。应用程序应根据用户角色限制对某些URI的访问。它应该提供密码更改选项,并允许Admin用户更改其他用户的角色 在下面的示例中,每次向服务器发出HTTP请求时,数据库都会被CustomUserDetailsService点击,以加载用户的当前详细信息,这似乎对性能有很大影响: public class JwtAuthenticationFilter extends OncePerReques
Admin
用户更改其他用户的角色
在下面的示例中,每次向服务器发出HTTP请求时,数据库都会被CustomUserDetailsService
点击,以加载用户的当前详细信息,这似乎对性能有很大影响:
public class JwtAuthenticationFilter extends OncePerRequestFilter {
//...
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
try {
String jwt = getJwtFromRequest(request);
if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
Long userId = tokenProvider.getUserIdFromJWT(jwt);
UserDetails userDetails = customUserDetailsService.loadUserById(userId);
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception ex) {
logger.error("Could not set user authentication in security context", ex);
}
filterChain.doFilter(request, response);
}
//...
}
本教程的作者建议了另一种选择:
注意,您还可以在JWT声明中对用户的用户名和角色进行编码,并通过从JWT解析这些声明来创建UserDetails对象
然而,这样做的代价是很难改变用户的角色,因为我们无法丢弃已发行的令牌,而不跟踪它们
可能的解决办法
我研究了JWT的主题,并提出了以下解决方案:
让我们在JWT声明中存储用户名和角色,并设置一个较短的令牌过期时间(使用exp
claim)-在这段时间后,例如15分钟,我们点击数据库检查用户的详细信息。如果角色已更改,我们将在有效负载中使用新角色生成新令牌。如果密码已更改,我们要求用户在生成新令牌之前重新验证
此解决方案的一个明显缺点是,用户访问权限的任何更改都会在过期后生效
问题:
在使用JWTs时,有没有其他方法来解决处理用户详细信息更改的问题?我们使用带有Spring Security和Angular webapp的JWT令牌 我认为你的
可能的解决方案
想法是有效的。我们以类似的方式处理这个问题。我们的身份验证流程如下所示:
- 用户在URL处登录,响应头包含JWT令牌
- JWT令牌有一个短超时(分钟)
- webapp以更短的时间间隔ping“刷新令牌”服务,该服务检测令牌是否有效。如果是这样,服务器将重新发布一个新的令牌,其中包括用户的任何更新角色,然后由webapp存储,以便在将来对后端的请求中包含该令牌
这完全取决于您的用例。正如我所说,“刷新”服务对我们很有效。检查此筛选器实现: