为了账号安全,请及时绑定邮箱和手机立即绑定

添加“授权”标头会导致Spring Security保护允许的端点

添加“授权”标头会导致Spring Security保护允许的端点

波斯汪 2022-09-07 17:45:31
所以,我有这个在我的WebSecurityConfigurerAdapterpublic 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();                }}这不应该安全。如果我在标头中没有调用该终结点,则允许请求,但是如果我添加标头,则会收到 http 响应代码。/api/v1/notificationAuthorization: Basic abcdHTTPAuthorization: Basic abcd401注意:只是随机的,所以没有这样的用户在我的数据库中Basic abcd问题是,为什么添加 http 标头会使端点再次受到保护?Authorization...
查看完整描述

1 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

好问题,这可能有点令人困惑,因为这意味着合法客户端,只是密码错误,就可以被拒绝一个没有凭据的世界其他地方可以看到的页面。


实际上,这是设计使然。一般来说,授权系统需要先知道用户是谁,然后才能知道用户是否可以执行 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。


查看完整回答
反对 回复 2022-09-07
  • 1 回答
  • 0 关注
  • 74 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信