【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

【Spring Boot】Spring Boot 2.x + Spring Security OAuth2 2.3.3 出现 bad client credentials 错误的踩坑记录_第1张图片

{
    "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);
            }
        };
    }

这样看起来请求是一切正常的。

但是!!!

根据评论的小伙伴【@街头诗人sp https://me.csdn.net/sp_studio】 的提示,spring security文档中提示了可以在密码前加入一段内容,来使用特别的encoder进行操作。

https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-encoding

While this password is not stored in a secure format, it does allow for other passwords to be stored in a secure format. We can also request the users to change their password which would update the hash it was stored in.

For astute readers, it might be obvious that you can also migrate plain text passwords by prefixing them with {noop}. For example, with a password of

password

you can simply prefix the password with {noop} like:

{noop}password

因此,简单的在密码前拼接{noop}即可

同理,也支持拼接{sha256}等方法提示spring使用的加密方式

注意,实际应用中不要使用明文密码!数据库中存储的密码应当是加密过的,明文密码后患无穷。

你可能感兴趣的:(Spring,Boot,/,Spring,Cloud,spring,boot,spring,security,oauth)