Chirdeep Tomar Chirdeep Tomar - 8 days ago 4
Java Question

Spring Security with OAuth2 and JWT: Encoded password does not look like BCrypt

I am trying to implement a spring AuthorizationServer with JWT. I was able to produce JWT tokens and login until I added BCrypt to the mix. Now, when I am trying to login, I get "Bad credentials" from the 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);
});
}


Thanks for your help.

Answer

I needed to make the following change to get it to work. If anyone else needs it.

@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;
    }