16

我正在使用spring boot,并且我在WebSecurityConfigurerAdapter中启用了全局方法安全性

@EnableGlobalMethodSecurity(prePostEnabled = true, order = Ordered.HIGHEST_PRECEDENCE) 

下面是我的控制器代码

@PreAuthorize("hasAnyRole('admin') or principal.id == id")
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public User updateUser(@PathVariable("id") String id,  @Valid @RequestBody   UserDto userDto) 
{ ....}

但是,当非管理员用户尝试执行 PUT 请求时,JSR303 验证器将在 @PreAuthorize 之前启动。例如,非管理员用户最终会得到类似“需要名字”而不是“拒绝访问”的内容。但是在用户提供名字变量以通过验证器后,拒绝访问被返回。

有谁知道如何在@Valid 或@Validated 之前强制检查@PreAuthorize?

而且我必须使用这种方法级别的授权而不是基于 url 的授权来执行一些复杂的规则检查。

4

3 回答 3

3

我有同样的问题,我找到了这篇文章。M. Deinum 的评论帮助我理解出了什么问题

这是我所做的:

  1. 公共方法具有@PreAuthorize 并进行检查
  2. @RequestBody 参数上没有@Valid
  3. 我创建了第二种方法,私有的,我在其中进行DTO 验证。使用@Valid 注解
  4. 公共方法将调用委托给私有方法。仅调用私有方法是授权公共方法

例子 :

@RequestMapping(method = RequestMethod.POST)
@PreAuthorize("hasRole('MY_ROLE')")
public ResponseEntity createNewMessage(@RequestBody CreateMessageDTO createMessageDTO) {
    // The user is authorized
    return createNewMessageWithValidation(createMessageDTO);
}

private ResponseEntity createNewMessageWithValidation(@Valid CreateMessageDTO createMessageDTO) {
   // The DTO is valid
   return ...
}
于 2016-08-26T12:08:44.507 回答
0

对于相同的场景,我发现了通过弹簧过滤器实现安全性的建议。
这是类似的帖子:How to check security access (@Secured or @PreAuthorize) before validation (@Valid) in my Controller?

此外,也许是一种不同的方法 - 尝试通过在 @InitBinder 中注册自定义验证器来使用验证(因此跳过 @valid 注释)。

要访问过滤器类中的主体对象:

  SecurityContextImpl sci = (SecurityContextImpl)     
session().getAttribute("SPRING_SECURITY_CONTEXT");

if (sci != null) {
    UserDetails cud = (UserDetails) sci.getAuthentication().getPrincipal();

 }

在这种情况下 /{id} 是 URL 中的路径参数。要访问过滤器或拦截器类中的路径参数:

String[] requestMappingParams =    ((HandlerMethod)handler).getMethodAnnotation(RequestMapping.class).params()

        for (String value : requestMappingParams) {.
于 2015-03-08T07:49:59.277 回答
0

使用WebSecurityConfigurerAdapter.configure(HttpSecurity http)代替@PreAuthorize

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
  @Override
  protected void configure(HttpSecurity http) throws    Exception {
    http
      .authorizeRequests()
      .mvcMatchers( "/path/**").hasRole("admin");
  }
}
于 2019-07-15T04:10:10.200 回答