如何将资源提供给具有相应userid的用户



我使用keycloak保护我的后端(spring boot)作为资源服务器,并且我的前端在头中使用jwt令牌调用后端上的资源,这意味着当User1进行GET/products调用时返回这样的json结构:

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

当一个已登录的用户创建一个产品时,将当前已登录用户的userid分配给该产品。例如,用户id为(f114298c-8b38-47e7-b413-bd8f12exyz)的User1创建了productOne和productTwo。

我的问题是:如何使用用户id (f114298c-8b38-47e7-b413-bd8f12exyz)制作产品当前登录的User1有相应的userid吗?因此,当User2登录时,他看不到分配给User1的产品。User2只能看到自己创建的具有相应userid的产品。

我希望我没有把问题复杂化,提前谢谢!

配置spring REST API作为资源服务器。如果您不知道如何操作,请参考我编写的这篇教程(如果您已经配置了资源服务器,它还可以向您展示如何简化安全配置)。

然后,当请求被授权时,您应该在安全上下文中有AbstractOAuth2TokenAuthenticationToken<?>的子类(除非您像我在第二和第三教程中那样显式更改它)

  • @EnableMethodSecurityin your security-conf
  • 注入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')")

最新更新