将JWT与基于角色的授权一起使用

mikee2509

背景

我正在使用Spring Security开发一个Web应用程序,并尝试首次使用JSON Web令牌进行身份验证。该应用应根据用户角色限制对某些URI的访问。它应该提供密码更改选项,并使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声明)-在此期间(例如15分钟)后,我们进入数据库以检查用户的详细信息。如果角色已更改,我们将在有效负载中生成具有新角色的新令牌。如果密码已更改,我们要求用户在生成新令牌之前重新进行身份验证。

该解决方案的一个明显缺点是,用户访问权限的任何更改在到期时间段之后都是有效的。

还有其他方法可以解决使用JWT时处理用户详细信息更改的问题吗?

库加

我们将JWT令牌与Spring Security和Angular webapp一起使用。

我认为你的Possible Solution想法是正确的。我们以类似的方式处理。我们的身份验证流程如下所示:

  • 用户在URL上登录,并且响应标头包含JWT令牌
  • JWT令牌的超时时间(分钟)很短
  • Web应用程序会在较短的间隔内对“刷新令牌”服务执行ping操作,以检测令牌是否有效。如果是这样,服务器将为用户重新发行包括任何更新角色的新令牌,然后由Webapp存储,以包含在对后端的将来请求中。

由于提供了“刷新”服务,如果用户的角色发生更改或被系统禁止,他们将自动获悉新角色,或者不迟于令牌到期时间被“锁定”。

多年来,这对我们来说一直很好。我们用户的角色不会经常更改,并且如果需要立即更新其角色,则可以随时注销/重新登录。

其他潜在解决方案

但是,如果最重要的是要立即在系统中更新用户的角色,则可以让Spring的Filter在每个请求中检查JWT标头,并执行JWT验证,并在每个请求上添加新的,刷新的JWT令牌。响应。

然后,您的客户端可以期望从服务器返回的每个响应上获得修订的JWT令牌,并将该修订的JWT令牌用于每个后续请求。

这可以工作,但是如果您的流量很大,则费用也相对较高。

这完全取决于您的用例。就像我说的那样,“刷新”服务对我们来说效果很好。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

基于角色的jwt授权

将FileContentResult与未经授权的结果一起使用

将KeyVaultClient与MSAL令牌“未授权”一起使用

将end()与基于文本的索引一起使用

17.04:将matplotlib与基于GTK的后端一起使用?

将 mongodb 与基于类的视图 django 一起使用

客户端JWT基于角色的授权

将3scale与共享的OAuth授权服务器一起使用

将授权的Google Cloud Endpoints与Google登录一起使用

将PayPal授权和捕获与参考交易一起使用

将Twilio Enqueue动词与HTTP Basic Auth一起使用时未授权401

HTTP GET Jwt请求与邮递员一起使用,但与axios返回相同401未经授权

无法将 pkcs11-tool 与自定义 hsm 角色一起使用

使用JWT受众字段来授权角色

带有 Spring Security 的 JWT 基于角色的授权

Spring Boot JWT令牌基于角色的授权问题

使用Spring Security的基于角色的授权

如何将flask_jwt_extended与蓝图一起使用?

.NET Core:如何将基于csproj的项目与project.json一起使用?

将boost asio stream_handle与基于文件的顺序设备一起使用

如何将 async/await 与需要基于回调的异步活动的 SDK 一起使用

将龙卷风与aiohttp(或其他基于asyncio的库)一起使用

将矩阵c \ c ++ API与基于行的索引一起使用

将折叠式工具栏与基于片段元素的布局一起使用

基于类的视图 - 使用 FormView 将多个模型组合在一起

查询:将Karate DSL与基于JavaScript的UI自动化框架一起使用

将 push_back() 与基于范围的 for 循环一起使用

将基于类的视图 UpdateView 与 2 个主键模型一起使用

如何将withcolumn方法与基于多个条件的过滤器一起使用?