Spring Boot OAuth2升级至2.0.0.RELEASE后调用/oauth/token报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
相关产品推荐
相关产品推荐

