我使用的是Spring授权服务器1.0.0,在这里我按照我的要求定制了JWT,如下所示,假设有一个用户“vinay”,他的角色也是“vinay”。
我正在添加额外字段“权限”:JWT中的[{“role”:“ROLE_vinay”}]。下面是JWT的有效负载。{ "sub": "vinay", "aud": "messaging-client", "nbf": 1671430162, "authority": [ { "role": "ROLE_vinay" } ], "scope": [ "openid" ], "iss": "http://localhost:8000", "exp": 1671430462, "iat": 1671430162 }
角色“vinay”有多个权限/限制。此数据存在于MySQL中。用户验证(登录)后,我将此数据添加到Redis中的KEY:VALUE对中,其中key是“vinay”,value是[限制1,权限1,权限2]。"vinay" : [Permission 1, Permission 2, Restriction 1]
用户成功登录后(vinay),客户端获得自定义令牌,并将请求发送到spring资源服务器,请求头中带有自定义JWT,并带有Bearer前缀。对于每个请求,如何解码传入的JWT并获得“role”并从Redis验证?如果Redis中有任何限制,它应该不允许。它应该抛出“401 unauthorized”。如果有权限,则应着手处理该请求。
1条答案
按热度按时间4xrmg8kj1#
在你最新的评论中,你提到只使用MySQL,我认为这是有道理的。我认为Redis不适合这种情况。所以流程是:
1.在授权服务器中,使用
OAuth2TokenCustomizer<JwtEncodingContext>
将authority
字段添加到JWT(例如ROLE_xyz
)。1.在资源服务器中,使用
JwtGrantedAuthoritiesConverter
将JWT的authority
字段Map到Spring Security中的authentication.getAuthorities()
。挑战在于,在数据库中,您将角色直接Map到一组允许的URL(例如
ROLE_xyz
=〉POST /customer
,...)。也许您正在处理一个现有的数据库模式,无法从头开始设计数据或关系。我所期望的是将角色Map到一组权限(例如ROLE_xyz
=〉customer.write
,...)。如果您有这样的权限方案,您可以在上面的
JwtGrantedAuthoritiesConverter
中进行查找,并将这些权限Map为权限。但是,如果MySQL中的数据将角色Map到URL模式,则最好使用
AuthorizationManager
API将授权与MySQL表集成(有关示例,请参见Authorize HttpServletRequests with AuthorizationFilter下的 * Configure RequestMatcherDelegatingAuthorizationManager *)。可以实现一个定制的
AuthorizationManager
来查找ROLE_xyz
,并使用RequestMatcherDelegatingAuthorizationManager.builder()
动态构建授权规则列表。例如:
这看起来可能很复杂,但是您的授权方案(使用OAuth2 + JWT AND roles/authorities AND MySQL来管理角色)是一个有点复杂的设置,
AuthorizationManager
API实际上比Spring Security的早期版本更容易。另请注意,上面的示例假定数据库中的角色Map可以在运行时更改,因此每次都必须进行查找。如果不是这种情况,则可以将示例更改为仅在启动时从MySQL加载数据。如果需要,还可以使用高速缓存来提高MySQL查找性能。