如何使@PreAuthorize具有比@Valid或@Validated更高的优先级

use*_*165 9 controller spring-mvc spring-security role-base-authorization bean-validation

我使用的是spring boot,我在WebSecurityConfigurerAdapter中启用了全局方法安全性

@EnableGlobalMethodSecurity(prePostEnabled = true, order = Ordered.HIGHEST_PRECEDENCE) 
Run Code Online (Sandbox Code Playgroud)

以下是我的控制器代码

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

但是,当非管理员用户尝试执行PUT请求时,JSR303验证器将在@PreAuthorize之前启动.例如,非管理员用户最终得到类似"名字是必需的"而不是"拒绝访问"的内容.但是在用户提供了第一个名称变量以传递验证器之后,返回了拒绝访问.

有没有人知道在@Valid或@Validated之前如何强制执行@PreAuthorize?

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

小智 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();

 }
Run Code Online (Sandbox Code Playgroud)

在本例中,/{id} 是 URL 中的路径参数。要访问过滤器或拦截器类中的路径参数:

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

        for (String value : requestMappingParams) {.
Run Code Online (Sandbox Code Playgroud)