2013-07-03 11 views
40

Od wiosny Bezpieczeństwo 3.1.4.RELEASE, stare org.springframework.security.authentication.encoding.PasswordEncoderhas been deprecated na rzecz org.springframework.security.crypto.password.PasswordEncoder. Ponieważ moja aplikacja nie została jeszcze udostępniona publicznie, zdecydowałem się przejść do nowego, nieużytego API.Jak korzystać z nowego PasswordEncodera ze Spring Security

Do tej pory miałem ReflectionSaltSource, który automatycznie używał daty rejestracji użytkownika jako soli dla użytkownika na hasło.

String encodedPassword = passwordEncoder.encodePassword(rawPassword, saltSource.getSalt(user)); 

Podczas procesu logowania, Wiosna stosowany również moje fasoli przywłaszczyć sprawdzić, czy użytkownik może lub nie może podpisać się nie mogę to osiągnąć w nowym hasłem enkodera, ponieważ domyślna implementacja SHA-1. - StandardPasswordEncoder ma tylko możliwość dodania globalnej sekretnej soli podczas tworzenia kodera.

Czy istnieje rozsądna metoda konfiguracji z nieużytym API?

Odpowiedz

48

Jeśli w rzeczywistości nie zarejestrowano żadnych użytkowników z istniejącym formatem, najlepiej byłoby zamiast tego przejść na stronę BCrypt password encoder.

To o wiele mniej kłopotów, ponieważ nie musisz martwić się o sól - detale są całkowicie zamknięte wewnątrz enkodera. Używanie BCrypt jest silniejsze niż użycie zwykłego algorytmu skrótu, a także jest standardem, który jest kompatybilny z aplikacjami używającymi innych języków.

Nie ma powodu, aby wybierać inne opcje dla nowej aplikacji.

+3

Co jeśli masz zarejestrowanych użytkowników? Zakładam, że Password enoder zostanie w pewnym momencie usunięty. Jak migrować? – Marc

+7

Migracja kont zwykle wymaga ponownego hashowania hasła, gdy użytkownik loguje się. Musisz również obsługiwać wiele algorytmów dla okresu migracji. Poza tym możesz wymagać zresetowania hasła lub ostatecznie zablokować lub usunąć nieużywane konta, które nie były używane przez dodatkowy okres. To zależy od twojego systemu i wymagań. Jestem pewien, że możesz znaleźć dyskusje na ten temat, jeśli przeprowadzisz wyszukiwanie, ponieważ jest to powszechny problem i staje się coraz bardziej trafny, gdy wzrasta liczba haseł związanych z dbaniem o hasło. Przynajmniej nie używasz [zwykłego tekstu] (http://ow.ly/qZQh0) :-). –

+1

Mam aplikację, która działa i używa starego PasswordEncodera z solą. Czy istnieją przykłady migracji do nowego PasswordEncodera? – user2213684

3

Po przejściu przez Internet, aby przeczytać o tym i opcje na wiosnę I dalszy odpowiedź Luke, użyj BCrypt (wspomniano w source code na wiosnę).

Najlepszy zasób, jaki znalazłem, aby wyjaśnić, dlaczego hash/sól i dlaczego używać BCrypt jest dobrym wyborem tutaj: Salted Password Hashing - Doing it Right.

+0

Podczas korzystania z bcrypt jest dobrym pomysłem, artykuł, z którym się łączysz, ma wiele okropnych pomysłów, takich jak używanie szybkiego hashu. Zobacz szczegóły w Reddit http://www.reddit.com/r/programming/comments/1yrnbo/salted_password_hashing_doing_it_right/cfnaqkl –

17

Oto implementacja BCrypt, która działa dla mnie.

w wiosenno-security.xml

<authentication-manager > 
    <authentication-provider ref="authProvider"></authentication-provider> 
    </authentication-manager> 
<beans:bean id="authProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> 
    <beans:property name="userDetailsService" ref="userDetailsServiceImpl" /> 
    <beans:property name="passwordEncoder" ref="encoder" /> 
</beans:bean> 
<!-- For hashing and salting user passwords --> 
    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> 

W klasie java

PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
String hashedPassword = passwordEncoder.encode(yourpassword); 

Bardziej szczegółowy przykład zabezpieczenia sprężynowego Click Here

nadzieję, że to pomoże.

Dzięki

+0

Co zawiera Twój userDetailsServiceImpl? – Richard

5

Miałem podobny problem. Potrzebowałem zachować zaszyfrowane hasła (Base64/SHA-1/Random salt Encoded), ponieważ użytkownicy nie będą chcieli zmieniać swoich haseł ani się ponownie rejestrować. Chciałem jednak użyć enkodera BCCCrównież do przodu.

Moje rozwiązanie było napisanie zamówienie dekoder, który sprawdza, aby sprawdzić, które metody szyfrowania użyto zanim dobieraniu (BCrypted te zaczynają się $).

Aby obejść problem z solą, przechodzę do dekodera połączonego Ciąg soli + zaszyfrowanego hasła przez mój zmodyfikowany obiekt użytkownika.

Dekoder

@Component 
public class LegacyEncoder implements PasswordEncoder { 

    private static final String BCRYP_TYPE = "$"; 
    private static final PasswordEncoder BCRYPT = new BCryptPasswordEncoder(); 

    @Override 
    public String encode(CharSequence rawPassword) { 

    return BCRYPT.encode(rawPassword); 
    } 

    @Override 
    public boolean matches(CharSequence rawPassword, String encodedPassword) { 

    if (encodedPassword.startsWith(BCRYP_TYPE)) { 
     return BCRYPT.matches(rawPassword, encodedPassword); 
    } 

    return sha1SaltMatch(rawPassword, encodedPassword); 
    } 

    @SneakyThrows 
    private boolean sha1SaltMatch(CharSequence rawPassword, String encodedPassword) { 

    String[] saltHash = encodedPassword.split(User.SPLIT_CHAR); 

    // Legacy code from old system 
    byte[] b64salt = Base64.getDecoder().decode(saltHash[0].getBytes()); 
    byte[] validHash = Base64.getDecoder().decode(saltHash[1]); 
    byte[] checkHash = Utility.getHash(5, rawPassword.toString(), b64salt); 

    return Arrays.equals(checkHash, validHash); 
    } 

} 

obiektu użytkownika

public class User implements UserDetails { 

    public static final String SPLIT_CHAR = ":"; 

    @Id 
    @Column(name = "user_id", nullable = false) 
    private Integer userId; 

    @Column(nullable = false, length = 60) 
    private String password; 

    @Column(nullable = true, length = 32) 
    private String salt; 

.
.

@PostLoad 
    private void init() { 

    username = emailAddress; //To comply with UserDetails 
    password = salt == null ? password : salt + SPLIT_CHAR + password; 
    }   

Można również dodać hak ponownie zakodować hasło w nowym formacie BCrypt i należy go wymienić. Tym samym wycofanie starej metody.

Powiązane problemy