【问题标题】:Spring Security with OAuth2 and JWT: Encoded password does not look like BCrypt使用 OAuth2 和 JWT 的 Spring Security:编码密码看起来不像 BCrypt
【发布时间】:2017-04-03 15:07:01
【问题描述】:

我正在尝试使用 JWT 实现 Spring AuthorizationServer。在我添加 BCrypt 之前,我能够生成 JWT 令牌并登录。现在,当我尝试登录时,我从 API 获得“错误凭据”。

OAuth2Configuration.java

@Configuration
@EnableAuthorizationServer
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {

    private DataSource dataSource;
    private AuthenticationManager authenticationManager;
    private BCryptPasswordEncoder passwordEncoder;

    public OAuth2Configuration(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
        this.dataSource = new Jdbc3PoolingDataSource();
        this.passwordEncoder = new BCryptPasswordEncoder();
    }

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

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("api-client")
                .secret("verysecretivesecret")
                .scopes("READ", "WRITE", "DELETE")
                .authorizedGrantTypes("implicit", "refresh_tokens", "password", "authorization_code");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authorizationCodeServices(authorizationCodeServices())
                .tokenStore(tokenStore())
                .tokenEnhancer(jwtTokenEnhancer())
                .authenticationManager(authenticationManager);
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtTokenEnhancer());
    }

    @Bean
    protected JwtAccessTokenConverter jwtTokenEnhancer() {
        return new JwtAccessTokenConverter();
    }

    @Bean
    protected AuthorizationCodeServices authorizationCodeServices() {
        return new JdbcAuthorizationCodeServices(dataSource);
    }

}

WebSecurityConfig.java

@Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private AccountDetailsService accountDetailsService;
    private BCryptPasswordEncoder passwordEncoder;
    private DataSource dataSource;

    WebSecurityConfig(AccountDetailsService accountDetailsService) {
        this.accountDetailsService = accountDetailsService;
        this.dataSource = new Jdbc3PoolingDataSource();
        this.passwordEncoder = new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(accountDetailsService).passwordEncoder(passwordEncoder).and().jdbcAuthentication().dataSource(dataSource);
    }
}

SeedData.java

@Override
public void run(String... args) throws Exception {      

    Stream.of("alan,test").map(x -> x.split(","))
            .forEach(tuple -> {
                Account user = new Account();
                user.setUsername(tuple[0]);
                user.setPassword(new BCryptPasswordEncoder().encode(tuple[1]));
                user.setEmail(tuple[0]);
                user.setRoles(Collections.singletonList(role));
                user.setActive(true);
                this.accountRepository.save(user);
            });
}

感谢您的帮助。

【问题讨论】:

  • 数据库中的密码是否经过BCrypt编码?
  • @Jeff 是的。 user.setPassword(new BCryptPasswordEncoder().encode(tuple[1]));

标签: java spring spring-security spring-cloud spring-security-oauth2


【解决方案1】:

这是因为您对 WebSecurity 和 AuthorizationServer 都应用了 BCrypt。因此,您不仅需要在商店中保留 BCrypt 加密的用户密码,还需要为 OAuth2 保留 BCrypt 加密的客户端机密。我想这不是你试图接近的。

为了使您的代码正常工作,请删除

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

或者手动加密你的“verysecretivesecret”

【讨论】:

  • 是的,我也是这么想的,所以我把它删除了,但也没有用。
【解决方案2】:

我需要进行以下更改才能使其正常工作。如果其他人需要它。

@Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(accountDetailsService)
                    .passwordEncoder(passwordEncoder)
                    .and()
                    .authenticationProvider(authenticationProvider())
                    .jdbcAuthentication()
                    .dataSource(dataSource);
        }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(accountDetailsService);
        authenticationProvider.setPasswordEncoder(passwordEncoder);
        return authenticationProvider;
    }

【讨论】:

  • 感谢分享!真的帮了我
  • 有没有机会告诉我我做错了什么here - 看起来我遇到了同样的问题,但背后似乎有另一个原因。
猜你喜欢
  • 2021-03-20
  • 2020-05-26
  • 1970-01-01
  • 2019-03-25
  • 1970-01-01
  • 2021-12-12
  • 2018-10-09
  • 2019-12-01
  • 1970-01-01
相关资源
最近更新 更多