添加'Authorization'标头会导致Spring Security保护允许的端点 [英] Adding 'Authorization' header causes Spring Security to secure a permitted endpoint

查看:135
本文介绍了添加'Authorization'标头会导致Spring Security保护允许的端点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我的 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 的安全.如果我在 HTTP 标头中调用没有 Authorization:Basic abcd 的端点,则允许请求,但是如果我添加 Authorization:Basic abcd 标头,我得到一个 401 http响应代码.

which should not secure /api/v1/notification. If I call that endpoint without Authorization: Basic abcd in the HTTP header the request is permitted, but if I add the Authorization: Basic abcd header, I get a 401 http response code.

NB:基本abcd 只是随机的,因此我的数据库中没有这样的用户

NB: Basic abcd is just random so no such user is in my database

问题是,为什么在http标头中添加 Authorization ... 会使端点再次受到保护?

The question is why adding Authorization... in the http header makes the endpoint secured again?

推荐答案

很好的问题,这可能会造成混淆,因为这意味着可以将只有一个错误密码的合法客户端拒之门外,以免其他用户访问该页面.没有凭证就可以看到世界.

Good question, this can be kind of confusing since it means that a legitimate client, just with a bad password, could be denied a page that the rest of the world can see without credentials.

实际上,这是设计使然.一般来说,授权系统需要先知道用户是谁,然后才能知道用户是否可以执行X,Y或Z操作.即使使用公共端点,当用户处于上下文中时,端点的行为也可能会有所不同.因此,实际上,它们是首先进行身份验证的独立系统:如果请求提供凭据,则框架将尝试对用户进行身份验证,并相应地接受或拒绝该请求.

Actually, it's by design. Generally speaking, an authorization system would need to know who the user is before knowing whether the user can do X, Y, or Z operation. And even with a public endpoint, it's possible that the endpoint may behave differently when a user is in context. So, really, they are separate systems with authentication coming first: If a request presents credentials, then the framework will try and authenticate the user and accept or deny the request accordingly.

我意识到您没有要求解决该问题(您可能对行为完全满意,并且很好奇),但是您可以对 BasicAuthenticationFilter 进行的一项操作是将其配置为忽略故障,仅适用于该端点:

I realize you didn't ask for how to address it (you may be completely satisfied with the behavior and just curious), but one thing you can do with BasicAuthenticationFilter is configure it to ignore failures, just for that endpoint:

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中的过滤器:

And then replace the filter in the DSL:

http
    .httpBasic()
        .withObjectPostProcessor(
            new ObjectPostProcessor<BasicAuthenticationFilter>() {
                public BasicAuthenticationFilter postProcess(BasicAuthenticationFilter filter) {
                    return new IgnoreFailuresBasicAuthenticationFilter(filter);
                }
            });

此操作将允许过滤器链继续运行,即使基本身份验证失败也是如此.结果是,在身份验证失败的情况下,您将获得403而不是401.

What this will do is allow the filter chain to continue, even though Basic authentication failed. The consequence would be that, in the case authentication fails, you'd get a 403 instead of a 401.

这篇关于添加'Authorization'标头会导致Spring Security保护允许的端点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆