密码的加密和匹配
1 为什么需要对密码进行加密和匹配
用户输入的密码原则上即使是超级管理员也是不能知道密码的,所以在用户进行注册时不是直接将用户的密码存储到数据库中,而是将用户的密码经过加密后存放到数据库的;当用户注册完后进行登录时,先根据用户名到数据库中去查找数据,如果有数据就将用户的信息查询出来,此时查询出来的用户密码是经过加密的,但是用户登录时输入的密码又是没有加密的,就需要对用户的数据的密码进行注册时密码加密规则进行加密后再跟从数据库中查询到的用户密码进行匹配。
2 springSecurity提供了一个接口来实现密码的加密和匹配
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.security.crypto.password; public interface PasswordEncoder { String encode(CharSequence var1); boolean matches(CharSequence var1, String var2); }
技巧:我们需要自己实现这个接口,并在加密方法和匹配方法中编写一致的加密规则
3 如何实现自己的密码加密和匹配类
利用SpringSecurity提供的Md5PasswordEncoder类来实现我们的加密规则
3.1 编程步骤
前提:导入springSecurity的相关jar包【我使用的是springboot项目】
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.xiangxu</groupId> <artifactId>spring_security_system</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>spring_security_system</name> <description>Demo project for Spring Security</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--<dependency>--> <!--<groupId>org.springframework.boot</groupId>--> <!--<artifactId>spring-boot-starter-tomcat</artifactId>--> <!--<scope>provided</scope>--> <!--</dependency>--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.1.1 实现PasswordEncoder接口
3.1.2 利用Md5PasswordEncoder重写密码加密、匹配方法
package cn.xiangxu.spring_security_system.utils;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
/**
* 密码加密、匹配类
*/
@Component
public class MyPasswordEncoder implements PasswordEncoder {
/** 密码加密所需的参数,随便写 */
private final static String SALT = "fury";
/**
* 密码加密
* @param rawPassword 需要进行加密的原始密码
* @return 原始密码经过加密后的值
*/
@Override
public String encode(CharSequence rawPassword) {
Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
return md5PasswordEncoder.encodePassword(rawPassword.toString(), SALT);
}
/**
* 密码匹配
* @param rawPassword 原始密码
* @param encodedPassword 加密后的密码
* @return 原始密码和加密后的密码匹配就返回true,否则返回false
*/
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
return md5PasswordEncoder.isPasswordValid(encodedPassword, rawPassword.toString(), SALT);
}
}
package cn.xiangxu.spring_security_system.utils; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import static org.junit.Assert.*; @RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class MyPasswordEncoderTest { @Autowired private MyPasswordEncoder myPasswordEncoder; @Test public void encode() throws Exception { System.out.println("hello boy"); log.info("测试日志输出"); String password = "123456"; String result = myPasswordEncoder.encode(password); System.out.println("原始密码为:" + password); System.out.println("加密后的密码为:" + result); } @Test public void matches() throws Exception { String password01 = "123456"; String encodePassword = myPasswordEncoder.encode(password01); Boolean result = myPasswordEncoder.matches(password01, encodePassword); System.out.println("密码匹配结果为:" + result); } }