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對使用者密碼進行加密。
要使用新註冊的賬戶登入就需要在配置檔案中配置加密策略
配置後原來的賬號因為密碼沒有加密將不能使用
六、示例工程原始碼
示例工程已經上傳到碼雲上,如果有需要歡迎大家參考
示例工程
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。