在上一篇文章中,我们使用了用户详细信息服务,以便提供一种基于给定用户名从函数加载数据的方法。
用户详细信息的实现可能由内存机制,sql / no-sql数据库等支持。
选项是无限的。
关于密码存储,我们必须注意的是密码哈希。
出于安全原因,我们希望以散列形式存储密码。
假设有人未经授权访问了存储我们用户数据的表。 通过存储密码明文,用户可以检索系统中每个用户的密码。
因此,我们需要一种在将密码存储到数据库之前对密码进行哈希处理的方法。
始终注意,您的哈希必须健壮并且是最新的。
例如,MD5在过去非常流行,但如今导致安全性差。 实际上,如果使用gpu,可以很容易地破解MD5密码。
当涉及到密码编码时,Spring Security为我们提供了开箱即用的功能。
密码编码器是在授权过程中使用的接口。
package org.springframework.security.crypto.password;public interface PasswordEncoder {String encode(CharSequence rawPassword);boolean matches(CharSequence rawPassword, String encodedPassword);}
编码功能将用于编码您的密码,而matches功能将检查您的原始密码是否与编码后的密码匹配。 一旦您的用户详细信息服务从数据库中获取了用户信息,然后将使用从数据库中获取的密码来验证提供给授权的密码。 在这种情况下,spring将使用matchs函数。
现在,spring为我们提供了密码编码器的各种实现。
让我们尝试创建一个密码编码器bean。
package com.gkatzioura.security.passwordencoder.security;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
public class PasswordEncoderConfig {@Beanpublic PasswordEncoder passwordEncoder() {return new PasswordEncoder() {@Overridepublic String encode(CharSequence rawPassword) {return rawPassword.toString();}@Overridepublic boolean matches(CharSequence rawPassword, String encodedPassword) {return rawPassword.toString().equals(encodedPassword);}};}
}
该bean与Spring Boot附带的NoOpPasswordEncoder没什么不同。
不,我们将做一个小实验并添加一个自定义密码编码器。
我们的密码编码器会将用户提交的明文密码进行哈希处理,然后将其与数据库中等效用户已哈希的密码进行比较。
为了进行哈希处理,我们将使用bcrypt。
@Beanpublic PasswordEncoder customPasswordEncoder() {return new PasswordEncoder() {@Overridepublic String encode(CharSequence rawPassword) {return BCrypt.hashpw(rawPassword.toString(), BCrypt.gensalt(4));}@Overridepublic boolean matches(CharSequence rawPassword, String encodedPassword) {return BCrypt.checkpw(rawPassword.toString(), encodedPassword);}};}
为了测试这一点,我们将使用前面的文章中介绍的环境变量来设置安全性。
首先,我们需要对密码进行编码。 我们的系统不会以任何明文形式存储密码。
System.out.println(BCrypt.hashpw("user-password",BCrypt.gensalt(4)));
$2a$04$i4UWtMw6surai4dQMhoKSeLddi1XlAh2sSyG58K3ZvBHqVkhz8Y3y
因此,我们下一步要做的是在运行Spring Boot应用程序之前设置环境变量。
SPRING_SECURITY_USER_NAME=test-user
SPRING_SECURITY_USER_PASSWORD=$2a$04$i4UWtMw6surai4dQMhoKSeLddi1XlAh2sSyG58K3ZvBHqVkhz8Y3y
下一步是转到登录屏幕,并为凭据提供用户名和用户密码。
如您所见,您刚刚通过了身份验证。
在后台,spring散列了您提交的密码,并将其与通过环境变量存在的密码进行了比较。
翻译自: https://www.javacodegeeks.com/2018/06/security-spring-boot-password-encoder.html