2013-07-03 29 views
40

Kể từ Spring Security 3.1.4.RELEASE, cũ org.springframework.security.authentication.encoding.PasswordEncoderhas been deprecated có lợi cho org.springframework.security.crypto.password.PasswordEncoder. Vì đơn đăng ký của tôi chưa được công bố cho công chúng, tôi quyết định chuyển sang API mới, không được chấp thuận.Cách sử dụng PasswordEncoder mới từ Spring Security

Cho đến bây giờ, tôi đã có một ReflectionSaltSource tự động sử dụng ngày đăng ký của người dùng làm muối cho mỗi người dùng đối với mật khẩu.

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

Trong quá trình đăng nhập, mùa xuân cũng sử dụng đậu của tôi để chiếm đoạt xác minh nếu người dùng có thể hoặc không thể đăng nhập tôi không thể đạt được điều này trong bộ mã hóa mật khẩu mới, vì việc thực hiện mặc định của SHA-1. - StandardPasswordEncoder chỉ có khả năng thêm muối bí mật toàn cầu trong quá trình tạo bộ mã hóa.

Có phương pháp hợp lý nào về cách thiết lập nó với API không được chấp nhận không?

Trả lời

48

Nếu bạn chưa đăng ký bất kỳ người dùng nào với định dạng hiện có của mình thì tốt nhất bạn nên chuyển sang sử dụng số BCrypt password encoder.

Sẽ khó khăn hơn rất nhiều, vì bạn không phải lo lắng về muối chút nào - các chi tiết được đóng gói hoàn toàn bên trong bộ mã hóa. Sử dụng BCrypt mạnh hơn sử dụng thuật toán băm đơn giản và nó cũng là một tiêu chuẩn tương thích với các ứng dụng sử dụng các ngôn ngữ khác.

Thực sự không có lý do gì để chọn bất kỳ tùy chọn nào khác cho ứng dụng mới.

+3

Vậy nếu bạn thực sự có người dùng đã đăng ký thì sao? Tôi giả định rằng Passwordencoder sẽ được gỡ bỏ tại một số điểm. Cách di chuyển? – Marc

+7

Tài khoản di chuyển thường yêu cầu bạn băm mật khẩu khi người dùng đăng nhập thành công. Bạn cũng sẽ phải hỗ trợ nhiều thuật toán cho giai đoạn di chuyển. Ngoài ra, bạn có thể yêu cầu đặt lại mật khẩu hoặc cuối cùng là khóa hoặc xóa các tài khoản không sử dụng đã không được sử dụng trong một khoảng thời gian bổ sung. Nó phụ thuộc vào hệ thống và yêu cầu của bạn. Tôi chắc rằng bạn có thể tìm thấy các cuộc thảo luận về nó nếu bạn thực hiện một số tìm kiếm, vì đó là một vấn đề phổ biến và trở nên có liên quan hơn khi số lượng thỏa hiệp db mật khẩu tăng lên. Ít nhất bạn không sử dụng [plaintext] (http://ow.ly/qZQh0) :-). –

+1

Tôi có một ứng dụng đang hoạt động và đang sử dụng PasswordEncoder cũ với muối. Có ví dụ nào về cách di chuyển sang PasswordEncoder mới không? – user2213684

3

Chỉ cần đi vòng internet để đọc về điều này và các tùy chọn trong mùa xuân tôi sẽ thứ hai câu trả lời của Luke, sử dụng BCrypt (nó được đề cập trong source code tại mùa xuân).

Tài nguyên tốt nhất tôi tìm thấy để giải thích lý do băm/muối và lý do sử dụng BCrypt là một lựa chọn tốt là ở đây: Salted Password Hashing - Doing it Right.

+0

Trong khi sử dụng bcrypt là một ý tưởng hay, bài viết bạn liên kết có nhiều ý tưởng kinh khủng, chẳng hạn như sử dụng băm nhanh. Xem nhận xét reddit để biết chi tiết http://www.reddit.com/r/programming/comments/1yrnbo/salted_password_hashing_doing_it_right/cfnaqkl –

17

Đây là việc triển khai BCrypt đang hoạt động cho tôi.

vào mùa xuân-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"/> 

Trong lớp java

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

Ví dụ chi tiết hơn về an ninh mùa xuân Click Here

Hy vọng điều này sẽ giúp.

Cảm ơn

+0

Điều gì được chứa trong userDetailsServiceImpl của bạn? – Richard

5

Tôi gặp sự cố tương tự. Tôi cần giữ mật khẩu được mã hóa cũ (Base64/SHA-1/Muối ngẫu nhiên được mã hóa) vì người dùng sẽ không muốn thay đổi mật khẩu hoặc đăng ký lại. Tuy nhiên, tôi cũng muốn sử dụng bộ mã hóa BCrypt.

Giải pháp của tôi là viết bộ giải mã riêng biệt để kiểm tra xem phương thức mã hóa nào được sử dụng trước khi kết hợp (BCrypted bắt đầu bằng $).

Để khắc phục vấn đề về muối, tôi chuyển vào bộ giải mã được ghép nối Chuỗi muối + mật khẩu được mã hóa thông qua đối tượng người dùng đã sửa đổi của tôi.

Decoder

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

} 

đối tượng người dùng

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

Bạn cũng có thể thêm một cái móc để re-encode mật khẩu trong các định dạng bcrypt mới và thay thế nó. Do đó loại bỏ phương pháp cũ.

Các vấn đề liên quan