7

Próbuję zaimplementować Spring AuthorizationServer z JWT. Udało mi się wyprodukować tokeny JWT i zalogować się, dopóki nie dodałem BCrypt do miksu. Teraz, gdy próbuję się zalogować, otrzymuję "Złe poświadczenia" z interfejsu API.Spring Security z OAuth2 i JWT: Zakodowane hasło nie wygląda jak BCrypt

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

Dzięki za pomoc.

+0

Czy hasła w bazie danych BCrypt są zakodowane? – Jeff

+0

@Jeff tak, są. user.setPassword (nowe BCryptPasswordEncoder(). encode (tuple [1])); –

Odpowiedz

3

Musiałem wprowadzić następującą zmianę zmusić go do pracy. Jeśli ktokolwiek inny tego potrzebuje.

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

Dzięki za udostępnienie! Naprawdę mi pomógł – mario

+0

Czy jest szansa, że ​​możesz mi powiedzieć, co robię źle [tutaj] (https://stackoverflow.com/questions/49138227/oauth-token-full-authentication-is-required-to-access- this-resource) - Wygląda na to, że mam ten sam problem, ale wydaje się, że kryje się za tym inna przyczyna. – displayname

4

Jest tak, ponieważ zastosowałeś BCrypt zarówno do WebSecurity i AuthorizationServer. Musisz więc przechowywać nie tylko zaszyfrowane hasła BCrypt w swoim sklepie, ale także zaszyfrować zaszyfrowane hasła klienta OAuth2. Sądzę, że to nie było to, do czego próbujesz podejść.

Aby uczynić swój kod działa, albo usunąć

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

lub ręcznie zaszyfrować swoje „verysecretivesecret”

+0

Tak, myślałem tak samo, więc usunąłem to, ale to też nie zadziałało. –