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

Spring Boot OAuth2升级至2.0.0.RELEASE后调用/oauth/token报Unauthorized错误

解决Spring Boot 2.0 OAuth2 /oauth/token 401 Unauthorized问题

我之前在升级Spring Boot从1.5.x到2.0.x时也踩过这个坑,主要是因为Spring Boot 2.0配套的Spring Security 5.x对OAuth2的默认配置和规则做了不少调整,咱们一步步来修复:

1. 排除冲突的自动配置类

Spring Boot 2.0的SecurityAutoConfiguration会自动启用默认的安全拦截规则,这会和OAuth2的授权服务器配置冲突,导致/oauth/token接口被拦截。你需要在启动类上排除这些自动配置:

@SpringBootApplication(exclude = {
    SecurityAutoConfiguration.class,
    ManagementSecurityAutoConfiguration.class
})
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

2. 适配密码编码器的变化

Spring Security 5.x废弃了NoOpPasswordEncoder(明文密码编码器),要求必须显式指定密码编码器。你需要在授权服务器配置中添加密码编码器Bean,并且在配置客户端时对密码进行编码:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        // 使用Spring提供的默认密码编码器,支持多种加密方式
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("your-client-id")
                // 这里要对客户端密码进行编码
                .secret(passwordEncoder().encode("your-client-secret"))
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("read", "write")
                .accessTokenValiditySeconds(3600)
                .refreshTokenValiditySeconds(86400);
    }

    // 其他配置(比如token存储、授权端点等)...
}

3. 确保/oauth/token接口允许匿名访问

你需要在WebSecurityConfigurerAdapter的配置中,明确放行/oauth/token等OAuth2相关接口,避免被拦截:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 直接忽略这些接口的安全检查
        web.ignoring().antMatchers("/oauth/token", "/oauth/check_token", "/oauth/error");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                // 或者在这里显式允许访问token接口
                .antMatchers("/oauth/token").permitAll()
                .anyRequest().authenticated();
    }

    // 配置AuthenticationManager(如果用密码模式的话)...
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

4. 检查请求参数和请求头是否正确

调用/oauth/token接口时,必须满足以下要求:

  • 使用POST请求
  • 参数以form-data形式传递,必须包含grant_type=password、username、password
  • 请求头必须携带Authorization: Basic {base64(clientId:clientSecret)},其中{base64(clientId:clientSecret)}是把你的客户端ID和密码用冒号拼接后做Base64编码的结果

比如,客户端ID是client,密码是secret,那么Base64编码结果是Y2xpZW50OnNlY3JldA==,请求头就是Authorization: Basic Y2xpZW50OnNlY3JldA==

最后总结

这些问题本质上都是Spring Boot 2.0升级带来的Spring Security 5.x的安全规则变化,只要调整对应的配置,适配新的密码编码机制和拦截规则,就能解决401 Unauthorized的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:55:57