Nic*_*e11 6 spring-security jwt spring-boot
我正在使用 JWT 令牌授权。我正在尝试限制对某些 REST api 端点的访问。我希望它像这样工作:下面的代码应该仅在经过身份验证的用户 id == 中给出的 id 时执行@PathVariable
@PreAuthorize("hasAnyAuthority('ADMIN', 'USER')")
@GetMapping(value = "orders/{id}", produces = "application/json")
public EntityModel<Order> getOrders(@PathVariable Long id) { ... )
Run Code Online (Sandbox Code Playgroud)
我不明白CustomPermissionEvaluator implements PermissionEvaluator在我的情况下第二个链接应该是什么样子。如果有人能给我一些提示,我将不胜感激。
我的第二个问题是,我以后能做的就是获取 username authentication.getName(),然后我必须使用UserRepositoryto findUserByUsername(String username)。这样做正常吗?这是额外的数据库查询。我想知道是否可以以某种方式将 userID 添加到令牌(因为返回的函数UsernamePasswordAuthenticationToken已经通过用户名获取用户)。
要触发PermissionEvaluator,您必须使用hasPermission()in @PreAuthorize。有 2 个版本hasPermission():
(1)@PreAuthorize("hasPermission('foo' ,'bar')") 将调用
boolean hasPermission(Authentication authentication, Object targetDomainObject,Object permission);
/** targetDomainObject = 'foo', permission = 'bar' **/
Run Code Online (Sandbox Code Playgroud)
(2) @PreAuthorize("hasPermission('foo' ,'bar','baz')")将调用
boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission);
/** targetId = 'foo' , targetType = 'bar' , permission = 'baz' **/
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,Authentication参数都是Authentication从SecurityContext.
需要注意的一件事是,在配置时 @PreAuthorize("hasPermission()"),您可以使用spring data 中的 或#foo来指定 protected 方法中的哪个参数将用于调用. 请参阅此了解更多详细信息。@P@ParamPermissionEvaluator
对于你的情况,你可以这样做:
@PreAuthorize("hasPermission('#id', 'getOrder')")
public EntityModel<Order> getOrders(@PathVariable Long id) {
}
Run Code Online (Sandbox Code Playgroud)
看起来PermissionEvaluator像:
public class MyPermissionEvaluator implements PermissionEvaluator {
@Override
public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) {
MyAuthentication myAuth = (MyAuthentication) auth;
Long targetId = (Long) id;
String permssionStr = (String) permission;
if(permssionStr.equals("getOrder")){
return myAuth.getUserId().equals(targetId);
}else if(permssionStr.equals("xxxx"){
//other permission checking
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,它假设您还自定义了包含 userID 的Authentication令牌MyAuthentication。它还回答了您的第二个问题,即您可以自定义身份验证过程以返回自定义Authentication令牌,您可以在加载用户记录进行身份验证后将 userId 设置到其中。这样,userId就会保存在里面MyAuthentication,不需要再在里面查询了PermissionEvaluator。
或者,对于这种简单的情况,您也可以考虑直接在 中 表达授权逻辑,而@PreAuthorize无需使用:hasPermission()
@PreAuthorize("#id == authentication.userId")
public EntityModel<Order> getOrders(@PathVariable Long id) {
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8091 次 |
| 最近记录: |