Spring security实现对账户进行加密
一、原理分析1.1加密原理
首先前端页面发送注册的账户信息到controller层,然后依次经过service层和dao层,最后入库。其中对密码的加密应该放在service层进行,加密后再入库。
spring security中有一个加密类BCryptPasswordEncoder可以用来对密码进行加密,调用其中的encode方法返回一个加密后的字符串
public String encode(CharSequence rawPassword) { String salt; if (strength > 0) { if (random != null) { salt = BCrypt.gensalt(strength, random); } else { salt = BCrypt.gensalt(strength); } } else { salt = BCrypt.gensalt(); } return BCrypt.hashpw(rawPassword.toString(), salt); }
使用时可以在spring的配置文件中配置一个加密类的bean,这样在service中可以直接注入
加密后数据库中存储的是加密过后的字符串。
1.2加密后的登录过程
对密码进行加密后数据库中存储的是加密字符串,用户发起登录请求后,框架会使用相同的加密算法对前端传递的密码进行加密并得到加密字符串,然后和数据库中查询到的字符串进行对比。
二、代码实现
具体的工程代码可以参考我的工程示例,下文中只给出了和添加用户相关的部分。
在配置文件中配置加密类
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"> </bean>
2.1添加用户的页面如下, register.html
<html> <head> <meta charset="UTF-8"> <title>注册页面</title> </head> <body> <form action="/user/add.do" method="post"> 用户名:<input type="text" name="username" placeholder="请输入用户名"><br> 密 码:<input type="password" name="password" placeholder="请输入密码"><br> <input type="submit" value="注册"> </form> </body> </html>
2.2controller层创建一个增加用户的方法
@RestController @RequestMapping("/user") public class UserController { @Autowired private IUserService userService; @PostMapping("/add") public String add(UserInfo userInfo){ userService.add(userInfo); return "success"; } }
2.3service层
@Autowired private BCryptPasswordEncoder passwordEncoder; ...//省略其他 @Override public void add(UserInfo userInfo) { //对密码加密 userInfo.setPassword(passwordEncoder.encode(userInfo.getPassword())); userDao.add(userInfo); }
这里的passwordEncoder就是在配置文件中配置的加密bean,注入后可以直接使用
dao层这里就不再列举了。
三、测试
启动工程并成功登录后,跳转到首页,
选择注册新账号后跳转到注册页面
输入账户和密码后注册,会在数据库中插入一条新的记录。
这里我页面上输入的是 admin/admin,数据库中存储的password是加密后的
$2a$10$URSaaafrPOCjFYvhrhQbku2/l36IJ0zH0G8xeJzf5lAH2F1JJ1ybG
四、用加密后的账号登录
此时如果使用刚刚新建的这个账号进行登录就会登录失败。因为我们并没有配置spring security认证时的加密方式,默认是不进行加密,所以会直接将前台输入的密码和数据库中的加密字符串进行比较。
要使用这个账号登录还需要进行如下配置
在spring security的配置文件中配置加密策略
<security:authentication-manager> <!--配置使用给定的userservice完成认证--> <security:authentication-provider user-service-ref="userService"> <security:password-encoder ref="passwordEncoder"/> </security:authentication-provider> </security:authentication-manager> <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"> </bean>
在userService的loadUserByUsername方法中去除密码字符串上拼接的{noop}字符串,本来这个就是为了适配密码未加密的情况
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserInfo userInfo = userDao.findByUsername(username); User user=new User(userInfo.getUsername(),userInfo.getPassword(),getRoles()); return user; }
然后使用刚才注册的 admin/admin就可以登录成功了。
注意如果进行了上面两部,数据库中以前的账户将不能进行登录了,因为数据库中的密码是没有加密的,而框架会对前台传递的密码进行加密后再和数据库中的比较。所以一定要记住上面新注册的这个账号admin/admin
这里我给出admin对应的加密字符串
$2a$10$URSaaafrPOCjFYvhrhQbku2/l36IJ0zH0G8xeJzf5lAH2F1JJ1ybG
如果大家忘记了刚才注册的账号,可以在数据库中插入一条admin/admin的记录。
五、总结
添加账户主要是需要用spring security自带的加密类BCryptPasswordEncoder对用户密码进行加密。
要使用新注册的账户登录就需要在配置文件中配置加密策略
配置后原来的账号因为密码没有加密将不能使用
六、示例工程源码
示例工程已经上传到码云上,如果有需要欢迎大家参考
阅读排行
- 1Java Swing组件BoxLayout布局用法示例
- 2java中-jar 与nohup的对比
- 3Java邮件发送程序(可以同时发给多个地址、可以带附件)
- 4Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.Type异常
- 5Java中自定义异常详解及实例代码
- 6深入理解Java中的克隆
- 7java读取excel文件的两种方法
- 8解析SpringSecurity+JWT认证流程实现
- 9spring boot里增加表单验证hibernate-validator并在freemarker模板里显示错误信息(推荐)
- 10深入解析java虚拟机