升级到 Spring Boot 2.0.2 后 Spring Security .permitAll() 不再有效

Posted

技术标签:

【中文标题】升级到 Spring Boot 2.0.2 后 Spring Security .permitAll() 不再有效【英文标题】:Spring Security .permitAll() no longer effective after upgrading to Spring Boot 2.0.2 【发布时间】:2018-11-20 10:29:03 【问题描述】:

我使用向移动应用程序公开 REST API 的 Web 应用程序。我将 Spring Boot 版本从 1.5.3.RELEASE 升级到 2.0.2.RELEASE,在修复了一些重大更改后,我面临一个无法解决的问题。

我关注了 Spring Boot 2.0 Migration Guide 和 Spring Boot Security 2.0 并查看了 Security changes in Spring Boot 2.0 M4。

问题在于应用使用 JWT 身份验证,并且有一个端点 (/auth/login) 接受用户凭据并生成一个长期存在的 JWT 作为回报。

有一个过滤器检查客户端发送的JWT令牌,并确定客户端是否可以访问请求的资源。

自定义安全配置如下:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfiguration 

@Configuration
@Order(1)
public class AuthenticationConfiguration extends WebSecurityConfigurerAdapter 

    // Some dependencies omitted

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception 
        httpSecurity
                // we don't need CSRF because JWT token is invulnerable
                .csrf().disable()

                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()

                // don't create session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()

                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers(HttpMethod.GET, "/version/**").permitAll()
                // Some more antMatchers() lines omitted
                .antMatchers("/auth/**").permitAll()
                .anyRequest().authenticated();

        // Custom JWT based security filter
        httpSecurity
                .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);

        // disable page caching
        httpSecurity.headers().cacheControl();
    

    @Bean
    public PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

    @Bean
    public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception 
        return new JwtAuthenticationTokenFilter(jwtTokenUtil);
    


@Configuration
@Order(2)
public class ClientVersionSupportConfiguration extends WebMvcConfigurerAdapter 

    @Override
    public void addInterceptors(InterceptorRegistry registry) 
        registry
                .addInterceptor(versionCheckingFilter())
                .addPathPatterns("/**")
                .excludePathPatterns("/error"); // Some more endpoints omitted
    

    @Bean
    public VersionCheckingInterceptor versionCheckingFilter() 
        return new VersionCheckingInterceptor();
    

注意.antMatchers("/auth/**").permitAll() 行。 /auth 端点应该可以在没有 JWT 的情况下访问,因为当用户尚未登录时,JWT 尚未生成。

在升级 Spring Boot 之前,它可以正常工作,现在无法正常工作。检查 JWT 的过滤器拒绝登录尝试。看起来.permitAll() 没有让请求通过。 /version/** 也不起作用。从浏览器中点击它会出现错误页面。

我还尝试从配置中删除行,直到仍然存在:

httpSecurity
        .authorizeRequests()
                .antMatchers("/auth/**").permitAll()

它没有帮助。您能帮忙恢复原来的行为吗?

【问题讨论】:

找到了一个使用相同模式并适用于 Spring Boot 2 的演示应用程序。在 Github question 中寻求帮助 【参考方案1】:

您是否有 api 的基本路径,例如/api?

server.contextPath 默认 Spring 属性名称已更改为 server.servlet.context-path

因此,如果您为您的 api 使用默认基本路径,您将找不到您期望的端点。除非你更新属性;)

【讨论】:

是的,这就是解决方案!安全配置很好,但如果没有未添加的 /api,端点不匹配。进行重命名后,您建议它可以工作。非常感谢! 我们也遇到过这个问题。为什么 Spring 会引入这样的重大变化? 这里是发行说明:github.com/spring-projects/spring-boot/wiki/…

以上是关于升级到 Spring Boot 2.0.2 后 Spring Security .permitAll() 不再有效的主要内容,如果未能解决你的问题,请参考以下文章

将 Web 应用升级到 Spring Boot 2.4 后出现 IllegalStateException

Spring Boot - 从 2.2.5 升级到 2.3.0 后验证停止工作

升级到 Spring Boot 2.2.2 后应用程序启动缓慢

升级到 Spring Boot 2.6.1 和 Spring Cloud 2021.0.0 后 Spring Cloud Stream 启动错误

将 Spring Boot 从 2.4.X 升级到 2.6.X 后无法运行我的 jar

升级到 Spring Boot 2 后,如何向 prometheus 公开缓存指标?