You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Security中permitAll()匹配排除URL失效问题求助

解决Spring Boot OAuth2资源服务器中特定端点跳过角色校验的问题

我帮你排查过很多类似的配置问题,核心原因其实是Spring Security的规则匹配是按顺序执行的——如果你把通用的/api/v1/**规则放在了放行规则前面,所有请求都会先命中这个通用规则,触发角色校验,后面的permitAll规则根本没机会生效。

正确的配置方式

你只需要调整规则的顺序,把需要放行的特定端点规则放在最前面,再配置通用的保护规则即可。下面是具体的代码示例:

旧版配置(基于ResourceServerConfigurerAdapter

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                // 先放行目标端点,顺序必须在通用规则之前!
                .antMatchers("/api/v1/test-data").permitAll()
                // 再保护所有/api/v1下的其他端点
                .antMatchers("/api/v1/**").hasRole("API_ACCESS")
                // 其他请求默认要求认证
                .anyRequest().authenticated();
    }
}

新版配置(Spring Security 5.7+ 推荐的lambda风格)

如果你用的是较新的Spring Security版本,建议使用更简洁的lambda配置:

@Configuration
public class ResourceServerConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                // 优先放行特定端点
                .requestMatchers("/api/v1/test-data").permitAll()
                // 保护剩余的/api/v1路径
                .requestMatchers("/api/v1/**").hasRole("API_ACCESS")
                // 其他所有请求需认证
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt
                    // 这里配置你的JWT解析逻辑,比如jwkSetUri等
                )
            );
        return http.build();
    }
}

额外排查点

如果调整顺序后还是不生效,可以检查这几个地方:

  • 路径匹配是否完全一致:比如你的请求是/api/v1/test-data/(带末尾斜杠),但配置的是不带斜杠,这时候可以用.antMatchers("/api/v1/test-data/**")来匹配所有子路径
  • 是否有其他配置类冲突:如果项目中还有其他WebSecurityConfigurerAdapterSecurityFilterChain配置,可能会覆盖当前规则,需要确保所有规则的优先级正确
  • 是否开启了CSRF保护:OAuth2资源服务器通常不需要CSRF,但如果开启了,可能会对某些请求造成影响,可以尝试临时关闭测试:http.csrf().disable()

测试验证

配置完成后,你可以用工具直接访问/api/v1/test-data,确认不需要携带OAuth2 token就能返回数据;而访问其他/api/v1/下的端点时,必须携带包含API_ACCESS角色的token才能正常访问。

内容的提问来源于stack exchange,提问作者Exact Finder

火山引擎 最新活动