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"/>
và
@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.
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
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