2011-10-05 59 views
50

Có hướng dẫn nào ở đó hay không có ai có chỉ dẫn về cách thực hiện những điều sau đây với Spring-Security?Xác thực tùy chỉnh bảo mật mùa xuân và mã hóa mật khẩu

Nhiệm vụ:

tôi cần để có được muối từ cơ sở dữ liệu của tôi cho tên người dùng chứng thực và sử dụng nó để mã hóa mật khẩu được cung cấp (từ trang đăng nhập) để so sánh nó với mật khẩu mã hóa lưu trữ (aka xác thực người dùng). thêm

thông tin:

tôi sử dụng một cấu trúc cơ sở dữ liệu tùy chỉnh. Đối tượng UserDetails được tạo thông qua tùy chỉnh UserDetailsService mà lần lượt sử dụng DAOProvider tùy chỉnh để nhận thông tin từ cơ sở dữ liệu.

security.xml tập tin của tôi cho đến nay:

<authentication-manager> 
    <authentication-provider user-service-ref="userDetailsService"> 
    </authentication-provider> 
</authentication-manager> 

bây giờ tôi nghĩ tôi sẽ cần

 <password-encoder hash="sha" /> 

nhưng những gì khác? Làm thế nào để bảo mật mùa xuân sử dụng muối databaseprovided để mã hóa mật khẩu?


chỉnh sửa:

tôi thấy This SO bài được informatative nhưng chưa đủ: Nếu tôi xác định một nguồn muối trong xml của tôi để được sử dụng bởi các bộ mã hóa mật khẩu, như vậy:

 <password-encoder ref="passwordEncoder">     
      <salt-source ref="saltSource"/> 
     </password-encoder> 

Tôi sẽ phải viết một SaltSource tùy chỉnh để sử dụng muối tùy chỉnh của mình. Nhưng điều đó không được tìm thấy bên trong đối tượng UserDetails. Vì vậy, ...

Alternative 1:

Tôi có thể sử dụng một thực hiện tùy chỉnh của UserDetails mà sau đó có thể có tài sản muối?

<beans:bean id="saltSource" class="path.to.MySaltSource" 
    p:userPropertyToUse="salt"/> 

@Service("userDetailsService") 
public class UserDetailsServiceImpl implements UserDetailsService { 
    public UserDetails loadUserByUsername(String username) 
      throws UsernameNotFoundException, DataAccessException { 

     // ... 
     return buildUserFromAccount(account); 
    } 

    @Transactional(readOnly = true) 

    UserDetailsImpl buildUserFromAccount(Account account){ 

     // ... build User object that contains salt property 
} 

tùy chỉnh lớp User:

public class UserDetailsImpl extends User{ 

    // ... 

    private String salt; 

    public String getSalt() { return salt; } 

    public void setSalt(String salt) { this.salt = salt; } 
} 

security.xml:

<authentication-manager> 
    <authentication-provider user-service-ref="userDetailsService"> 
     <password-encoder hash="sha">     
     <salt-source ref="saltSource"/> 
    </password-encoder> 
    </authentication-provider> 
</authentication-manager> 

<beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource" p:userPropertyToUse="salt"/> 


Phương án 2:

Nếu không tôi sẽ phải tiêm AccountDAO tôi vào SaltSource để trích xuất các muối cho một userName đưa ra từ cơ sở dữ liệu.

NHƯNG: Bảo mật mùa xuân gọi số SaltSource như thế nào?Luôn luôn với saltSource.getSalt(userDetails)?

Sau đó, tôi chỉ cần đảm bảo rằng SaltSource sử dụng userDetails.accountName trên số accountDAO để lấy muối.


Edit2:

Chỉ cần biết rằng cách tiếp cận của tôi là .. di sản .. :(Vì vậy, tôi nghĩ tôi sẽ chỉ cần sử dụng StandardPasswordEncoder (mà tôi vẫn phải tìm ra cách để sử dụng chính xác

BTW: Tôi đã triển khai tùy chọn đầu tiên với lớp UserDetails tùy chỉnh mở rộng lớp Người dùng và chỉ thêm thuộc tính muối sau đó được chuyển đến SaltSource như một userPropertyToUse giống như nó đã được đề xuất trong bài đăng SO được đề cập trong Chỉnh sửa 1 ...


EDIT 3:

Chỉ có các StandardPasswordEncoder làm việc, vì vậy tôi sẽ để lại một số gợi ý ở đây:

Sử dụng StandardPasswordEncoder cho Xác thực:

<beans:bean id="encoder" 
    class="org.springframework.security.crypto.password.StandardPasswordEncoder"> 
</beans:bean> 


<authentication-manager> 
    <authentication-provider user-service-ref="userDetailsService"> 
     <password-encoder ref="encoder" />   
    </authentication-provider> 
</authentication-manager> 

này đòi hỏi sự module an ninh mùa xuân-mã hóa trong phiên bản 3.1.0.RC? theo như tôi biết. Không thể tìm thấy bất kỳ kho lưu trữ nào có 3.0. phiên bản (mặc dù một nơi nào đó nó có các phiên bản được liệt kê bao gồm 3.0.6 và như vậy). Ngoài ra các tài liệu nói về an ninh mùa xuân 3.1 vì vậy tôi figured, tôi sẽ chỉ đi với điều đó.

Khi tạo user (đối với tôi chỉ là một quản trị viên có thể làm điều đó), tôi chỉ sử dụng

 StandardPasswordEncoder encoder = new StandardPasswordEncoder(); 
     String result = encoder.encode(password); 

và tôi đang thực hiện.

Bảo mật mùa xuân sẽ ngẫu nhiên tạo muối và thêm nó vào chuỗi mật khẩu trước khi lưu trữ trong cơ sở dữ liệu để không cần cột muối nữa. Tuy nhiên, người ta cũng có thể cung cấp một muối toàn cầu làm đối số hàm tạo (new StandardPasswordEncoder("12345");), nhưng tôi không biết cách thiết lập cấu hình bảo mật của mình để lấy giá trị đó từ bean thay vì cung cấp một chuỗi tĩnh với <constructor-arg name="secret" value "12345" />. Nhưng tôi không biết bao nhiêu đó là cần thiết anyway.

Trả lời

34

tôi sẽ đánh dấu đây là trả lời, như tôi đã giải quyết vấn đề của tôi và không có ý kiến ​​hoặc câu trả lời khác đã được đưa ra:

Sửa 1 - Alternative 1 trả lời cho câu hỏi ban đầu

NHƯNG tôi đã để tìm hiểu rằng tùy chỉnh mật khẩu muối là một phương pháp kế thừa không cần thiết trong Spring Security 3.1 nữa, như tôi mô tả trong

Chỉnh sửa 3 nơi tôi để lại một số gợi ý về cách sử dụng StandardPasswordEncoder cho các muối tự động được lưu trữ bằng mật khẩu.

+1

Bài đăng của bạn thực sự đã giúp tôi tôi gặp phải sự cố tương tự. +1 để tự giải quyết ^^ – user1431729

+4

Tôi sẽ đề xuất BCryptPasswordEncoder thay vì StandardPasswordEncoder. BCryptPasswordEncoder là một lựa chọn tốt hơn cả về an ninh và khả năng tương tác với ngôn ngữ khác – Farm

0

Để lấy muối toàn cầu từ một bean, sử dụng ngôn ngữ Xuân Biểu hiện hoặc SpEL.

<beans:bean id="encoder" 
     class="org.springframework.security.crypto.password.StandardPasswordEncoder"> 
    <constructor-arg value="#{someotherBean.somePropertyWithAGetterMethod"/> 
</beans:bean> 
Các vấn đề liên quan