Jür*_*hen 7 authorization exception spring-security spring-boot spring-restcontroller
今天我花了几个小时来解决向 Spring security 6.0 的迁移问题,将已弃用的authorizeRequests()
方法替换为authorizeHttpRequests()
. 我了解到,在幕后,这意味着用安全链中的FilterSecurityInterceptor
新内容替换旧内容。但是,如果您尝试注册数据库中已存在的用户
,我未经身份验证的注册端点已经得到了一些意外结果,该端点使用 JPA 验证的请求正文,并且还以 BadRequest = 400 进行应答。AuthorizationFilter
@Valid
当转向 AuthorizationFilter 时,有效的注册请求仍然按预期工作,但错误情况(验证失败以及已存在的用户)均回复 Unauthorized = 401,这对于未经身份验证的端点来说是不可接受的...
我可以通过链接解决这个问题(最终!)
.shouldFilterAllDispatcherTypes(false)
Run Code Online (Sandbox Code Playgroud)
到authorizeHttpRequests()
。
但现在我开始想知道,新的默认行为是否有意义......
相当不起眼的代码片段是:
@ResponseStatus(HttpStatus.BAD_REQUEST)
带注释的UserAlreadyExistsException
:@PostMapping("/api/register")
public ResponseEntity<Void> registerUser(@Valid @RequestBody UserDto userDto) {
service.registerUser(mapper.toEntity(userDto));
return ok().build();
}
Run Code Online (Sandbox Code Playgroud)
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http,
AuthenticationManager authenticationManager) throws Exception {
http.authenticationManager(authenticationManager)
//.authorizeRequests() <-- deprecated, but working, using SecurityFilterInterceptor
.authorizeHttpRequests()
.shouldFilterAllDispatcherTypes(false) // without this line weird behavior since default is true
.requestMatchers(HttpMethod.POST,"/api/register").permitAll()
// ... more requestMatchers and other stuff
}
Run Code Online (Sandbox Code Playgroud)
因此,我深入研究了 AuthorizationFilter - 如果您查看 Spring Security 6.0.1 中的以下代码片段,Javadoc 已经是矛盾的AuthorizationFilter
。第一个新方法的默认值与下面 3 个方法的默认值相矛盾:
/**
* Sets whether to filter all dispatcher types.
* @param shouldFilterAllDispatcherTypes should filter all dispatcher types. Default
* is {@code true}
* @since 5.7
*/
public void setShouldFilterAllDispatcherTypes(boolean shouldFilterAllDispatcherTypes) {
this.observeOncePerRequest = !shouldFilterAllDispatcherTypes;
this.filterErrorDispatch = shouldFilterAllDispatcherTypes;
this.filterAsyncDispatch = shouldFilterAllDispatcherTypes;
}
//...
/**
* Sets whether this filter apply only once per request. By default, this is
* <code>true</code>, meaning the filter will only execute once per request. Sometimes
* users may wish it to execute more than once per request, such as when JSP forwards
* are being used and filter security is desired on each included fragment of the HTTP
* request.
* @param observeOncePerRequest whether the filter should only be applied once per
* request
*/
public void setObserveOncePerRequest(boolean observeOncePerRequest) {
this.observeOncePerRequest = observeOncePerRequest;
}
/**
* If set to true, the filter will be applied to error dispatcher. Defaults to false.
* @param filterErrorDispatch whether the filter should be applied to error dispatcher
*/
public void setFilterErrorDispatch(boolean filterErrorDispatch) {
this.filterErrorDispatch = filterErrorDispatch;
}
/**
* If set to true, the filter will be applied to the async dispatcher. Defaults to
* false.
* @param filterAsyncDispatch whether the filter should be applied to async dispatch
*/
public void setFilterAsyncDispatch(boolean filterAsyncDispatch) {
this.filterAsyncDispatch = filterAsyncDispatch;
}
Run Code Online (Sandbox Code Playgroud)
更糟糕的是,如果您使用默认值,似乎存在绕过授权的相关漏洞,如下面的链接所述。所以我想知道, default=true for 是否shouldFilterAllDispatcherTypes
有意义 - 或者我在这里错过了一点吗?
https://security.snyk.io/vuln/SNYK-JAVA-ORGSPRINGFRAMEWORKSECURITY-3092126
我不确定这是否能回答您的问题,但您正在使用 AuthorizationManagerRequestMatcherRegistry 并且您正在查看 AuthorizationFilter。在这里检查此链接: 来源
/**
* Sets whether all dispatcher types should be filtered.
* @param shouldFilter should filter all dispatcher types. Default is {@code true}
* @return the {@link AuthorizationManagerRequestMatcherRegistry} for further
* customizations
* @since 5.7
*/
public AuthorizationManagerRequestMatcherRegistry shouldFilterAllDispatcherTypes(boolean shouldFilter) {
this.shouldFilterAllDispatcherTypes = shouldFilter;
return this;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2183 次 |
最近记录: |