Spring Boot 如何使资源对具有相应userid的用户可用

00jrzges  于 2022-12-12  发布在  Spring
关注(0)|答案(1)|浏览(139)

我用keycloak将我的后端(spring Boot )保护为资源服务器,我的前端使用头中的jwt标记调用后端上的资源,这意味着当User 1进行GET /products调用时,返回如下所示的json结构:

{
    "id": "639242400f6cc412b5b29f26",
    "userid": "f114298c-8b38-47e7-b413-bd8f12exyz",
    "productname": "productOne"
},
{
    "id": "63924a050f6cc412b5b29f27",
    "userid": "f114298c-8b38-47e7-b413-bd8f12exyz",
    "productname": "productTwo"

}, ....

当登入的使用者建立产品时,会将目前登入的使用者所拥有的使用者ID指派给产品。例如,使用者ID为(f114298 c-8b 38 - 47 e7-b413-bd 8 f12 exyz)的User 1建立了productOne和productTwo。
我的问题是:如何使用户ID为(f114298 c-8b 38 - 47 e7-b413-bd 8 f12 exyz)的产品可供当前登录的具有相应用户ID的User 1使用?因此,当User 2登录时,他看不到分配给User 1的产品。User 2只能看到他自己创建的具有相应用户ID的产品。
我希望我没有把问题复杂化,提前感谢!!

dldeef67

dldeef671#

将您的spring REST API配置为资源服务器。
然后,当请求被授权时,在安全上下文中应该有AbstractOAuth2TokenAuthenticationToken<?>的子类。

  • 安全配置中的@EnableMethodSecurity
  • 注入AbstractOAuth2TokenAuthenticationToken<?>作为控制器方法参数

根据您的需求和偏好,有两种选择(以下示例是为已使用@PreAuthorize("isAuthenticated()")装饰的@Controller设计的):

@GetMapping("/products")
@PreAuthorize("hasAuthority('READ_ANY_PRODUCT') || #auth.tokenAttributes['sub'] == #userid")
public List<ProductDto> listProducts(@RequestParam(required = true, name = "userid") @NotEmpty String userid, AbstractOAuth2TokenAuthenticationToken<?> auth) {
    final var products = productRepo.findByUserid(userid);
    ....
}

@GetMapping("/products")
public List<ProductDto> listProducts(AbstractOAuth2TokenAuthenticationToken<?> auth) {
    final var products = productRepo.findByUserid(auth.getTokenAttributes().get(StandardClaimNames.SUB).toString());
    ...
}

如果您按照上面链接的教程学习到3号,您将学习如何为Spring安全表达式构建自定义DSL,以构建类似如下的内容:

@PreAuthorize("is(#userid) or isProductManager() or onBehalfOf(#userid).can('read_product')")

相关问题