You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Boot中调整OAuth2过滤级别并指定路径权限?

问题分析与解决方案

你遇到的核心问题是自定义的WebSecurityConfigurerAdapter覆盖了Spring Security OAuth2默认的资源服务器配置,导致需要OAuth2保护的路径无法正确验证令牌。当你注释掉这个Bean时,默认的OAuth2配置生效,所以接口能正常工作。

为什么会出现这个问题?

Spring Security中,WebSecurityConfigurerAdapter和ResourceServerConfigurerAdapter的配置存在优先级关系:

  • ResourceServerConfigurerAdapter的默认Order是3,负责处理OAuth2资源服务器的认证逻辑(比如令牌验证)。
  • WebSecurityConfigurerAdapter的默认Order是100,负责通用的Web安全配置。

当你在自定义的WebSecurityConfigurerAdapter中使用authorizeRequests().anyRequest().hasRole("USER")时,这个配置会覆盖ResourceServer的规则,导致OAuth2的令牌过滤器没有被应用到你的API路径上,所以即使你携带了正确的令牌,请求也会被判定为无效。

正确的配置方式

我们需要把公共路径忽略和OAuth2资源保护分开配置:

1. 配置WebSecurity忽略无需过滤的路径

使用WebSecurity.ignoring()让这些路径完全跳过Spring Security的过滤器链,既高效又不会干扰OAuth2的配置:

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired 
    UserMapper userMapper;

    @Bean 
    PasswordEncoder passwordEncoder() { 
        return new BCryptPasswordEncoder(); 
    }

    @Bean 
    UserDetailsService userDetailsService() { 
        return username -> {
            User myU = userMapper.getUser(username);
            if (myU == null) {
                throw new UsernameNotFoundException("Could not find the user '" + username + "'");
            }
            return org.springframework.security.core.userdetails.User
                    .withUsername(myU.name)
                    .password(myU.password)
                    .authorities("USER", "write")
                    .build();
        };
    }

    // 忽略公共路径,完全不经过Spring Security过滤器
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
           .antMatchers("/robots.txt", "/error", "/login", "/doLogout", "/home", "/pageNotFound",
                        "/errorNonSamsung", "/snsandroidgear", "/snstheme", "/errorDesktop", "/*", "/getUrls",
                        "/css/**", "/js/**", "/fonts/**", "/img/**", "/dologin", "/form", "/addImage",
                        "/addThemeImage", "/exportUniqueToexcel", "/exporttoexcel", "/delete", "/activateDeactivate");
    }

    // 配置通用Web安全(比如表单登录等,不要覆盖OAuth2规则)
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
            .and()
            .httpBasic().disable();
    }
}

2. 单独配置ResourceServer保护API路径

创建ResourceServerConfigurerAdapter专门处理需要OAuth2验证的路径,确保令牌逻辑生效:

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            // 指定需要OAuth2保护的路径
            .requestMatchers()
                .antMatchers("/isTagAvailable")
                .and()
            // 配置权限要求
            .authorizeRequests()
                .anyRequest().hasAuthority("USER"); // 注意这里用hasAuthority,因为你配置的是authorities("USER", "write")
    }
}

验证效果

配置完成后,重新测试:

  • 公共路径(如/robots.txt)可以直接访问:
    $ curl http://localhost:8080/robots.txt
    User-agent: *
    Disallow: /
    
  • 获取令牌正常:
    $ curl -u xxxxxxx:xxxxxxx http://localhost:8080/oauth/token -d grant_type=password -d username=xxxxx -d password=xxxx -d client_id=xxxxxxx -d client_secret=xxxxxxx -d scope=write
    {"access_token":"f90b4bdf-a380-40d6-a6a7-5be28bd3ce99","token_type":"bearer","refresh_token":"cf507647-9f74-4ed7-a23e-92acac9ec257","expires_in":43199,"scope":"write"}
    
  • 携带令牌访问受保护的接口:
    $ curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer f90b4bdf-a380-40d6-a6a7-5be28bd3ce99" -d '{"apiKey": "samsung", "tag": "cnn"}' localhost:8080/isTagAvailable
    {"message":"CustomTag is not available","tagAvailable":false}
    

这样就能实现仅对指定路径进行OAuth2安全过滤,同时公共路径不受影响。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:01:48