PasswordEncoder密码解析器
上一篇文章
(本章节代码接着上篇来)
认证流程
当用户在浏览器中随意输入一个URL的时候, Spring Security 会判断当前登录是否已经被认证,如果已经认证,正常访问URL。如果没有被认证,那么就会跳转到loginPage()对应的URL中显示登录页面。等用户输入用户名和密码点击登录按钮后,发送登录url4。如果url和loginProcessingUrl()一样才会去执行登录流程。否则就需要重新认证。
执行登录流程时首先被UsernamePasswordAuthenticationFilter进行过滤,取出用户名和密码,放入到容器中。根据usernameParameter和passwordParameter进行取用户名和密码,如果没有配置这两个方法,默认为请求参数名username和password
执行自定义登录逻辑UserDetailsService的实现类。判断用户名是否存在和数据库中,如果不存在,直接抛出UsernameNotFoundException。如果用户名存在,把从数据库中查询出来的密码通过org.springframework.security.core.userdetails.User传递给Spring Security。Spring Security根据容器中配置的Password encoder示例把客户端传递过来的密码和数据库传递过来的密码进行匹配。如果匹配成功表示认证成功。
如果登录成功,跳转到successForwardUrl(转发)/successHandler(自己控制跳转方式)/defaultSuccessUrl(重定向)配置的URL。如果登录失败,跳转到failureForwardUrl/failureHandler/failureUrl
PasswordEncoder密码解析器
PasswordEncoder接口位于org.springframework.security.crypto.password包下
我们新建一个类去继承PasswordEncoder
/
* 凭证匹配器。
* 专门用于做认证流程的凭证校验使用的类型。
*/
public class SimplePasswordEncoder implements PasswordEncoder {
//把明文密码,加密成密文密码。
@Override
public String encode(CharSequence charSequence) {
System.out.println("加密逻辑执行");
return charSequence.toString();
}
//校验明文和密文是否匹配。
@Override
public boolean matches(CharSequence charSequence, String s) {
System.out.println("密码匹配逻辑执行");
return s.equals(encode(charSequence));
}
}
这个时候回到SecurityConfig类
这个时候我们就可以看到逻辑已经执行了~
MD5加密
Shiro框架
在过去使用Shiro框架的时候,就接触过MD5加密算法,然而实际上在SpringSecurity里面,操作会更加简单
public static void main(String[] args) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] one = digest.digest("alvin".getBytes());
byte[] two = digest.digest("admin".getBytes());
byte[] three = digest.digest("java".getBytes());
System.out.println("one = " + toString(one));
System.out.println("two = " + toString(two));
System.out.println("three = " + toString(three));
}
private static String toString(byte[]buf){
StringBuilder builder = new StringBuilder("");
for(byte b : buf){
String s = Integer.toHexString(b & 0xFF);
if(s.length() == 1){
builder.append("0");
}
builder.append(s);
}
return builder.toString();
}
那么现在就投入到应用当中
创建一个新类,继承PasswordEncoder接口
public class Md5PassWord implements PasswordEncoder {
@Override
public String encode(CharSequence charSequence) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] tmp = digest.digest(charSequence.toString().getBytes());
return MyToString(tmp);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return "";
}
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return s.equals(encode(charSequence));
}
private String MyToString(byte[] tmp){
StringBuilder builder = new StringBuilder("");
for(byte b : tmp){
String s = Integer.toHexString(b & 0xFF);
if(s.length() == 1){
builder.append("0");
}
builder.append(s);
}
return builder.toString();
}
}