2017-05-05 9 views
1

Ich implementiere OAuth 2.0 im Spring Boot. Wenn ein Benutzer seinen Benutzernamen/sein Passwort übergibt, versucht spring ihn zu authentifizieren, indem er das Passwort hasht und es mit dem bereits gehashten Passwort vergleicht. Aber Spring vermisst immer das Salz, so dass es immer schlechte Anmeldeinformationen zurückgibt.Wie kann ich das Salz an den Frühling weitergeben?

Wie kann ich das Salz an den Frühling weitergeben?

Hier meine UserDAO Klasse:

@Service 
public class UserDAO implements UserDetailsService, SaltSource{ 

private LoginDetails user; 
private UserDetailsImpl userDetailsImpl; 

@Autowired 
private LoginDetailsManager loginDetailsManager; 

@Override 
public UserDetails1 loadUserByUsername(String username) throws UsernameNotFoundException { 

    System.out.println("Get user"); 
    user = loginDetailsManager.getByUsername(username); 
    System.out.println(user.toString()); 
    if (user == null) { 
     throw new UsernameNotFoundException(
       "User " + username + " not found."); 
    } 

    GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_USER"); 
    List<GrantedAuthority> grantedAuthorities = new ArrayList<>(); 
    grantedAuthorities.add(grantedAuthority); 

    String password = user.getPasswordHash(); 
    String salt = user.getSalt(); 
    userDetailsImpl = new UserDetailsImpl(user.getUsername(), user.getPasswordHash(), salt, grantedAuthorities); 

    return new UserDetailsImpl(
      user.getUsername(), 
      user.getPasswordHash(), 
      salt, 
      grantedAuthorities); 
} 
} 

Nach meiner AuthorizationServer Klasse:

@Configuration 
@EnableAuthorizationServer 
protected class AuthorizationApplication extends AuthorizationServerConfigurerAdapter { 

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

    @Autowired 
    private PasswordEncoder passwordEncoder; 

    @Autowired 
    private AuthenticationManager authenticationManager; 


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


    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     clients.jdbc(dataSource); 
    } 


    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
     AuthorizationCodeServices services = getAuthorizationCodeServices(); 
     JdbcTokenStore tokenStore = getTokenStore(); 
     endpoints 
       .userDetailsService(userDetailsService) 
       .authorizationCodeServices(services) 
       .authenticationManager(authenticationManager) 
       .tokenStore(tokenStore) 
       .approvalStoreDisabled(); 
    } 

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

Von einem kleinen Debugging, fand ich, dass Frühling ihr Salz aus SaltSource (org.springframework bekommt. security.authentication.dao.SaltSource). Ich kann nicht herausfinden, wie ich diese Quelle konfigurieren kann.

+0

Weil ich SHA256 (Hash + Passwort) in meiner Datenbank habe - die ich aus der UserDAO-Klasse zu Spring als Eigenschaft 'user.getPasswordHash()' des UserDetailsImpl-Objekts zurückgeben. Spring vergleicht es mit SHA256 (Passwort) und ich bin nicht autorisiert. –

+0

Sorry, ich habe es nicht verstanden. Derzeit habe ich eine manuell gefüllte Datenbank zum Testen. Wie würde sich der Frühling ohne Salz authentifizieren? –

+0

Okay, bitte ertrage mich. Um Komplexität zu vermeiden, habe ich gerade eine neue Klasse erstellt, die PasswordEncoder implementiert (mit zwei Methoden - encode für simple sha256 Hashing und matches()) und sie anstelle von StandardPasswordEncoder verwendet. Gibt es eine Möglichkeit, eine SaltSource dafür zu konfigurieren? –

Antwort

1

konnte nicht einen Weg finden, damit meine eigenen PasswordEncoder und verwendet, um eine statische Variable Salz aus dem UserDAO passieren umgesetzt:

public class PasswordEncoderImpl implements PasswordEncoder { 

    public static Constants constants = new Constants(); 

    @Override 
    public String encode(CharSequence rawPassword) { 
     return DigestUtils.sha256Hex(rawPassword.toString()); 
    } 

    @Override 
    public boolean matches(CharSequence rawPassword, String encodedPassword) { 
     String salt = constants.getSalt(); 

/** 
* If salt is null, it means the value in constants object is empty now. 
* => client-secret validation is going on 
* => we just need the comparision of plain-text string. 
*/ 
     if(salt != null) { 
// case of password authentication 
      return DigestUtils.sha256Hex(salt + rawPassword).equalsIgnoreCase(encodedPassword); 
     } else { 
    //case of client-secret authentication 
     return rawPassword.equals(encodedPassword); 
     } 
    } 
} 

Einstellen der Wert von Konstanten Objekt in der loadUserByUsername Methode.

Verwandte Themen