如果userId匹配,Springboot允许访问端点

时间:2019-03-19 19:20:07

标签: spring-boot

我正在关注这个问题:

How to configure Spring Boot Security so that a user is only allowed to update their own profile

想象一下,我有一个端点void,如果用户尝试编辑它们自己(例如:ID为1的用户正在访问/user/edit/{id}但不能访问),我希望可以访问该端点/user/edit/1(如果他们是管理员),以便能够编辑任何用户。

在安全配置中有什么方法可以实现这一目标?

user/edit/2

将其限制为管理员用户,我需要管理员或与用户ID匹配的ID。

我唯一能想到的就是控制器内部有类似的东西

.antMatchers("/user/edit/**").hasRole("ADMIN")

但是我给人的印象是我们不应该在控制器中对访问逻辑进行编码?

2 个答案:

答案 0 :(得分:1)

要控制控制器中的角色访问,可以使用@Secured或@PreAuthorize之类的注释。

要使用@Secured,请在您的安全配置类中添加

@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
    // ...
}

现在您可以在控制器中使用它:

@Secured("ROLE_ADMIN")
@PostMapping
public Account post(Account account, double amount){
    // ...
}

要使用@PreAuthorize,请在您的安全配置类中添加:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig {
    // ...
}

现在您可以在控制器中使用它:

@PreAuthorize("hasAuthority('ROLE_ADMIN')")
@PostMapping
public Account post(Account account, double amount){
    // ...
}

有关更多信息,您可以check here Spring文档。

答案 1 :(得分:1)

可以使用Spring Security的Method Security Expressions来做到这一点。从文档复制的示例:

@PreAuthorize("#c.name == authentication.name")
public void doSomething(@P("c") Contact contact);

请阅读前面的部分,因为需要一些配置。另外请注意,如果重复使用表达式you can define your own security annotations

  

给我的印象是,我们不应该在访问代码中对访问逻辑进行编码   控制器?

恕我直言,“应该”这个词太强了。安全表达式功能强大,从理论上讲,您可以将所有安全检查与控制器逻辑分开。支票有误或遗失时更容易发现。如果要使用Swagger注释来记录端点,则也更容易与Swagger注释进行比较。

但是当您必须执行诸如返回过滤器行之类的操作时,它可能会变得更加棘手,这样用户只能看到某些结果。 Spring Security可以使用@PostFilter来做到这一点。但是有时它不是最佳的。例如,如果您知道某些行将不会返回,则可以运行一个更快的查询,而不是事后过滤掉行。

我的第一个Spring Security项目有这样的查询,所以自从我倾向于使用控制器逻辑而不是安全注释。但这不是从不使用批注的充分理由!因此,在可能的情况下,请务必使用安全性表达式,但是,如果您对它们有疑问或有其他考虑,则将安全性与控制器逻辑集成起来并不是一件容易的事。