Đăng ký với Spring Security – Mã hoá mật khẩu

22 tháng 02, 2021 – 4400 lượt xemBài viết gốc bạn hoàn toàn có thể xem ở đây .

1. Tổng quan

Bài viết này sẽ thảo luận về một phần quan trọng của quy trình đăng ký đó là mã hoá mật khẩu, chứ không đơn giản là lưu trữ mật khẩu gốc.

Đây là một vài cơ chế mã hoá mật khẩu được hỗ trợ bởi Spring Security và trong bài viết này, chúng ta sẽ sử dụng BCrypt, vì hiện tại nó là giải pháp tốt nhất.

Hầu hết những chính sách khác, như MD5PasswordEncoder và ShaPasswordEncoder sử dụng thuật toán yếu hơn và hiện tại không được dùng nữa .

2. Định nghĩa mã hoá mật khẩu

Chúng ta mở màn bằng định nghĩa BCryptPasswordEncoder đơn thuần như một bean trong thông số kỹ thuật của tất cả chúng ta :

@Bean
public PasswordEncoder encoder() {
    return new BCryptPasswordEncoder();
}

Ở những chính sách cũ hơn như SHAPasswordEncoder, nhu yếu người dùng gửi một salt value khi muốn mã hóa mật khẩu .

Tuy nhiên, BCrypt sẽ tự sinh ra một salt value ngẫu nhiên. Đây là điều quan trọng cần hiểu vì vậy mỗi lần chúng ta yêu cầu thì sẽ có một kết quả khác nhau và vì vậy chúng ta chỉ cần mã hoá mật khẩu một lần.

Để salt value tự sinh ra ngẫu nhiên, BCrypt sẽ tàng trữ salt trong chính hash value của nó. Ví dụ, trong hash value dưới đây :

$2a$10$ZLhnHxdpHETcxmtEStgpI./Ri1mksgJ9iDP36FmfMdYyVg9g0b2dq

Đây là ba trường được phân tách bởi USD :

  1. “2a” đại diện cho phiên bản thuật toán BCrypt 
  2. “10” đại diện cho độ dài của thuật toán
  3. “ZLhnHxdpHETcxmtEStgpI.” là một phần của chuỗi salt được sinh ra ngẫu nhiên. Về cơ bản, 22 ký tự đầu tiên là salt. Phần còn lại trong trường là phiên bản băm thực tế của văn bản thuần tuý.

Ngoài ra,  lưu ý rằng thuật toán BCrypt tạo ra một chuỗi có độ dài 60 ký tự, vì vậy chúng ta cần chắc chắn rằng mật khẩu sẽ lưu trữ ở trong cột có khả năng chứa nó. Một lỗi thường gặp là tạo một cột có độ dài khác 60 ký tự và sau đó sẽ gặp lỗi Invalid Username or Password trong quá trình xác thực.

3. Mã hoá mật khẩu trong đăng ký

Chúng ta sẽ sử dụng PasswordEncoder trong UserService của tất cả chúng ta để băm mật khẩu trong quy trình ĐK thông tin tài khoản :

Ví dụ 3.1. – UserService băm mật khẩu

@Autowired
private PasswordEncoder passwordEncoder;

@Override
public User registerNewUserAccount(UserDto accountDto) throws EmailExistsException {
    if (emailExist(accountDto.getEmail())) {
        throw new EmailExistsException(
          "There is an account with that email adress:" + accountDto.getEmail());
    }
    User user = new User();
    user.setFirstName(accountDto.getFirstName());
    user.setLastName(accountDto.getLastName());
    
    user.setPassword(passwordEncoder.encode(accountDto.getPassword()));
    
    user.setEmail(accountDto.getEmail());
    user.setRole(new Role(Integer.valueOf(1), user));
    return repository.save(user);
}

4. Mã hoá mật khẩu trong xác thực

Bây giờ tất cả chúng ta sẽ giải quyết và xử lý 50% còn lại của quy trình này là mã hóa mật khẩu khi người dùng xác nhận .Đầu tiên, tất cả chúng ta cần inject bean mã hóa mật khẩu để sớm xác lập authentication provider ( nhà cung ứng xác nhận ) của tất cả chúng ta :

@Autowired
private UserDetailsService userDetailsService;

@Bean
public DaoAuthenticationProvider authProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(encoder());
    return authProvider;
}

Cấu hình bảo mật rất đơn giản:

  • Chúng ta đang inject code của user details service
  • Chúng ta đang định nghĩa nhà cung cấp xác thực tham chiếu đến detail service của chúng ta
  • Chúng ta cũng kích hoạt mã hoá mật khẩu

Và cuối cùng, chúng ta cần tham chiếu đến nhà cung cấp xác thực trong cấu hình XML bảo mật của chúng ta:


    

Hoặc trong trường hợp này tất cả chúng ta sử dụng thông số kỹ thuật Java :

@Configuration
@ComponentScan(basePackages = { "com.baeldung.security" })
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider());
    }
    
    ...
}

5. Tổng kết

Hướng dẫn lần này là liên tục của chuỗi bài về Đăng ký, trình diễn về cách tàng trữ mật khẩu đúng cách trong cơ sở tài liệu bằng cách tận dụng BCrypt tuy đơn thuần nhưng rất mạnh .

Các đoạn code trên có thể xem ở GitHub này – đây là project ở Eclipse vì vậy nó rất dễ dàng import và chạy nó.

Đăng ký với Spring Security – Mã hoá mật khẩu

Bài viết liên quan
Hotline 24/7: O984.666.352
Alternate Text Gọi ngay