Spring security實(shí)現(xiàn)對賬戶進(jìn)行加密
一、原理分析1.1加密原理
首先前端頁面發(fā)送注冊的賬戶信息到controller層,然后依次經(jīng)過service層和dao層,最后入庫。其中對密碼的加密應(yīng)該放在service層進(jìn)行,加密后再入庫。
spring security中有一個加密類BCryptPasswordEncoder可以用來對密碼進(jìn)行加密,調(diào)用其中的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中可以直接注入
加密后數(shù)據(jù)庫中存儲的是加密過后的字符串。
1.2加密后的登錄過程
對密碼進(jìn)行加密后數(shù)據(jù)庫中存儲的是加密字符串,用戶發(fā)起登錄請求后,框架會使用相同的加密算法對前端傳遞的密碼進(jìn)行加密并得到加密字符串,然后和數(shù)據(jù)庫中查詢到的字符串進(jìn)行對比。
二、代碼實(shí)現(xiàn)
具體的工程代碼可以參考我的工程示例,下文中只給出了和添加用戶相關(guān)的部分。
在配置文件中配置加密類
<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層創(chuàng)建一個增加用戶的方法
@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層這里就不再列舉了。
三、測試
啟動工程并成功登錄后,跳轉(zhuǎn)到首頁,

選擇注冊新賬號后跳轉(zhuǎn)到注冊頁面

輸入賬戶和密碼后注冊,會在數(shù)據(jù)庫中插入一條新的記錄。

這里我頁面上輸入的是 admin/admin,數(shù)據(jù)庫中存儲的password是加密后的
$2a$10$URSaaafrPOCjFYvhrhQbku2/l36IJ0zH0G8xeJzf5lAH2F1JJ1ybG
四、用加密后的賬號登錄
此時如果使用剛剛新建的這個賬號進(jìn)行登錄就會登錄失敗。因?yàn)槲覀儾]有配置spring security認(rèn)證時的加密方式,默認(rèn)是不進(jìn)行加密,所以會直接將前臺輸入的密碼和數(shù)據(jù)庫中的加密字符串進(jìn)行比較。
要使用這個賬號登錄還需要進(jìn)行如下配置
在spring security的配置文件中配置加密策略
<security:authentication-manager>
<!--配置使用給定的userservice完成認(rèn)證-->
<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就可以登錄成功了。
注意如果進(jìn)行了上面兩部,數(shù)據(jù)庫中以前的賬戶將不能進(jìn)行登錄了,因?yàn)閿?shù)據(jù)庫中的密碼是沒有加密的,而框架會對前臺傳遞的密碼進(jìn)行加密后再和數(shù)據(jù)庫中的比較。所以一定要記住上面新注冊的這個賬號admin/admin
這里我給出admin對應(yīng)的加密字符串
$2a$10$URSaaafrPOCjFYvhrhQbku2/l36IJ0zH0G8xeJzf5lAH2F1JJ1ybG
如果大家忘記了剛才注冊的賬號,可以在數(shù)據(jù)庫中插入一條admin/admin的記錄。
五、總結(jié)
添加賬戶主要是需要用spring security自帶的加密類BCryptPasswordEncoder對用戶密碼進(jìn)行加密。
要使用新注冊的賬戶登錄就需要在配置文件中配置加密策略
配置后原來的賬號因?yàn)槊艽a沒有加密將不能使用
六、示例工程源碼
示例工程已經(jīng)上傳到碼云上,如果有需要?dú)g迎大家參考
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Spring Security基于散列加密方案實(shí)現(xiàn)自動登錄功能
- Spring security密碼加密實(shí)現(xiàn)代碼實(shí)例
- Spring Security使用數(shù)據(jù)庫認(rèn)證及用戶密碼加密和解密功能
- Spring?Security如何實(shí)現(xiàn)升級密碼加密方式詳解
- Python 內(nèi)置函數(shù)globals()和locals()對比詳解
- Python基礎(chǔ)教程之內(nèi)置函數(shù)locals()和globals()用法分析
- python內(nèi)置函數(shù)globals()的實(shí)現(xiàn)代碼
相關(guān)文章
Java中IO流簡介_動力節(jié)點(diǎn)Java學(xué)院整理
Java io系統(tǒng)的設(shè)計(jì)初衷,就是為了實(shí)現(xiàn)“文件、控制臺、網(wǎng)絡(luò)設(shè)備”這些io設(shè)置的通信。接下來通過本文給大家介紹Java中IO流簡介,感興趣的朋友一起看看吧2017-05-05
SpringBoot項(xiàng)目從搭建到發(fā)布一條龍
這篇文章主要介紹了SpringBoot項(xiàng)目從搭建到發(fā)布一條龍,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02
java集合List快速實(shí)現(xiàn)重復(fù)判斷的方法小結(jié)
在java編寫代碼中經(jīng)常會遇到某些重復(fù)判定或者去重的操作,本文主要為大家介紹了幾個常用方法,感興趣的小伙伴可以跟隨不想一起學(xué)習(xí)一下2024-12-12
Java+opencv3.2.0實(shí)現(xiàn)模板匹配
這篇文章主要為大家詳細(xì)介紹了Java+opencv3.2.0實(shí)現(xiàn)模板匹配的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-02-02
深入解析Java類加載的案例與實(shí)戰(zhàn)教程
本篇文章主要介紹Tomcat類加載器架構(gòu),以及基于類加載和字節(jié)碼相關(guān)知識,去分析動態(tài)代理的原理,對Java類加載相關(guān)知識感興趣的朋友一起看看吧2022-05-05

