【Spring Boot】Spring Boot 2.x + Spring Security OAuth2 2.3.3 出现 bad client credentials 错误的踩坑记录

环境:

spring boot 2.0.4.RELEASE

spring security oauth 2.3.3.RELEASE

OAuth2的配置

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userService;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client_1")
                .secret("123456")
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("read", "write")
                .accessTokenValiditySeconds(10000)
                .refreshTokenValiditySeconds(10000);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints){
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userService);
    }
    
}

Spring Security配置

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;

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

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    }

}

使用postman进行请求时,会提示bad client credentials

{
    "error": "invalid_client",
    "error_description": "Bad client credentials"
}

该请求甚至没有走到 UserDetailService 就已经被返回,很是诡异。

在网上搜索,查找相关技术博客,都无果。

其实问题出在 PasswordEncoder 身上,网上很多说明都没有写这个Bean的配置,如果不配置这个Bean的话AuthenticationManager 是直接初始化失败的,而Spring Security自带的这个Encoder,是对密码进行了一层加密,如果我们传铭文进去是会被直接报warn的log并且返回。

正确的使用姿势是:

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new PasswordEncoder() {
            @Override
            public String encode(CharSequence charSequence) {
                return charSequence.toString();
            }

            @Override
            public boolean matches(CharSequence charSequence, String s) {
                return Objects.equals(charSequence.toString(),s);
            }
        };
    }

这样请求就一切正常了,当然,实际应用中是不推荐这样的,因为数据库中存储的密码应当是加密过后的,明文密码后患无穷。

猜你喜欢

转载自blog.csdn.net/woluoyifan/article/details/81774139