所以,我的WebSecurityConfigurerAdapter
中有这个
public class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// Use this configuration for endpoints starting with 'api'
.antMatcher("/api/**")
// Do not secure endpoints receiving callbacks
.authorizeRequests().antMatchers(""/api/v1/notification").permitAll()
// Allow only users with role "ROLE_API"
.anyRequest().hasRole(Users.UserRoles.ROLE_API.role.replace("ROLE_", ""))
.and()
.httpBasic()
.and()
// Do not create any sessions
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// Disable csrf
.csrf().disable();
}
}
不应保护/api/v1/notification
的
。如果我在Authorization: Basic abcd
标头中调用不带HTTP
的端点,则允许该请求,但是如果我添加Authorization: Basic abcd
标头,则会得到一个401
http响应代码。>
注意:Basic abcd
只是随机的,因此我的数据库中没有这样的用户
问题是,为什么在http标头中添加Authorization...
会使端点再次受到保护?
答案 0 :(得分:1)
很好的问题,这可能会造成混淆,因为这意味着只有密码错误的合法客户端才能被拒绝访问该页面,而其他世界无需凭据即可看到该页面。
实际上,这是设计使然。一般来说,授权系统需要先知道用户是谁,然后再知道用户是否可以执行X,Y或Z操作。即使使用公共端点,当用户处于上下文中时,端点的行为也可能会有所不同。因此,实际上,它们是首先进行身份验证的独立系统:如果请求提供凭据,则框架将尝试对用户进行身份验证,并相应地接受或拒绝该请求。
我知道您并没有要求解决该问题(您可能对行为完全满意,并且很好奇),但是您可以使用BasicAuthenticationFilter
将其配置为忽略故障,只是为了该端点:
static class IgnoreFailuresBasicAuthenticationFilter extends BasicAuthenticationFilter {
private final BasicAuthenticationFilter everythingElse;
public IgnoreFailuresBasicAuthenticationFilter(BasicAuthenticationFilter everythingElse) {
super(everythingElse.getAuthenticationManager());
this.everythingElse = everythingElse;
}
protected void doFilterInternal(request, response, chain) {
if ("/api/v1/notification".equals(request.getPathInfo())) {
super.doFilterInternal(request, response, chain);
} else {
this.everythingElse.doFilterInternal(request, response, chain);
}
}
}
然后替换DSL中的过滤器:
http
.httpBasic()
.withObjectPostProcessor(
new ObjectPostProcessor<BasicAuthenticationFilter>() {
public BasicAuthenticationFilter postProcess(BasicAuthenticationFilter filter) {
return new IgnoreFailuresBasicAuthenticationFilter(filter);
}
});
此操作将允许过滤器链继续,即使基本身份验证失败也是如此。结果是,在身份验证失败的情况下,您将获得403而不是401。