首页 > 解决方案 > 服务中的 Spring Boot 授权

问题描述

我有一个 Spring Boot 应用程序,它使用 Spring Security 使用 JWT 来验证和授权请求。但是,某些请求应该只能由特定用户执行。例如:

GET /users/{id}/orders{id}如果是当前用户或当前用户是,则应仅返回订单列表ADMIN

PUT /orders/{id}仅当其payer是当前用户时才应编辑订单

PUT /representation-requests/{id}/accept仅当当前用户是target表示请求的用户时才应该工作

由于使用了 JWT,我获取当前用户 ID 的方式是

String userId = ((DecodedJWT) SecurityContextHolder.getContext().getAuthentication().getDetails()).getSubject();

我已经在负责处理每个 API 调用的服务的各种方法中实现了这一点。我的问题是使用 Spring Boot 和 Spring Security 是否有更通用的方法来做到这一点?或者这不是标准用例?

我查看@PreAuthorize了控制器中的注释,但它不适合我的需要,因为 URL 参数不足以检查嵌套实体。@PostAuthorize在控制器中似乎更接近,但由于 JWT 我无法让它工作(而且在注释中执行长代码似乎也有点笨拙,不确定它是否比在服务本身中执行更好)。我很欣赏一个正确方向的指针。

标签: javaspringspring-bootspring-security

解决方案


您将不得不尝试一下(我无法为您提供 JWT 的 100% 细节),但您基本上可以使用 SpEL 来实现您想要的。(不过,我不确定您为什么认为 @PostAuthorize 可能更合适)

像这样,对于简单的检查(# 表示方法参数)

@PreAuthorize("principal?.id == #id")
public List<Order> ordersForUsers(Integer id) {
    // do someting
}

或者像这样,委托给一个自定义bean(@表示一个bean名称,散列方法参数,'admin'你想要的角色,或者任何其他参数,真的)

@PreAuthorize("@yourBean.hasPermission(principal, #id, 'admin')")
public List<Order> ordersForUsers(Integer id) {
    // do someting
}

推荐阅读