shiro登錄過程


工作流程:

瀏覽器將用戶名、密碼、是否記住登錄等信息發送給登錄controller ,

new UsernamePasswordToken()獲取token,將用戶名、加密后的密碼、rememberMe,set到token中。SecurityUtils.getSubject();獲取subject對象,執行subect.login(token)進行登錄操作並捕獲可能出現的賬號密碼錯誤等異常。

 

1.前端登錄頁面將用戶名、密碼、是否記住登錄,傳入到Controller
Controller登錄方法:
 1 //1.獲取shiro中的subject對象
 2 Subject subject = SecurityUtils.getSubject();
 3 //2.對用戶從頁面輸入的密碼進行加密處理
 4 password = new Md5Hash(password,username,1024).toString();
 5 System.out.println("加密后的密碼: " + password);
 6 //3.創建shiro中的用戶名和密碼對象,將用戶輸入的用戶名密碼交給shiro管理
 7 UsernamePasswordToken token = new UsernamePasswordToken(username, password);
 8 //4.關於記住我的設置
 9 System.out.println("是否記住我: " + rememberMe);
10 if(rememberMe){
11     token.setRememberMe(true);
12 }
13 //5.調用shiro的登錄方法,調用后,shiro會自動執行Realm實現類===========
14 try {
15     subject.login(token);
16     System.out.println("開始登陸");
17 } catch (UnknownAccountException e) {
18     return new Result(1, "賬號不存在");
19 }catch (IncorrectCredentialsException e){
20     return new Result(1,"密碼錯誤");
21 }catch (AuthenticationException e){
22     System.out.println("其他異常");
23     return new Result(1,"其他異常");
24 }
25 return new Result(0, "登陸成功!");
26 
27 /**
28  * 注銷方法
29  * @return
30  */
31 public Result logout(){
32     //1.獲取subject對象
33     Subject subject =  SecurityUtils.getSubject();
34     //2.返回注銷方法
35     subject.logout();
36     //3.返回
37     return Result.ok("注銷成功");
38 }

獲取完數據后,shiro會自動執行Realm的實現類,實現類需要手動實現,如下:

 1 /**
 2  * projectName: myproject
 3  * @author: xxx
 4  * time: 2021/9/6 21:17
 5  * description:  自定義realm對象
 6  *
 7  *  1.從數據庫根據用戶名,取出數據庫中的用戶名,密碼交給shiro框架
 8  *  2.根據用戶名,到數據庫取出用戶對應的角色和權限對象交給shiro框架管理
 9  */
10 
11 public class MyUserRealm extends AuthorizingRealm {
12 
13     @Autowired
14     private UserService userService;
15     @Autowired
16     private MenuService menuService;
17     @Autowired
18     private RoleService roleService;
19     
20     /**
21      *     用戶輸入的用戶名和密碼輸入正確,校驗完成后進行賦值操作
22      *     根據用戶名到數據庫查詢這個用戶對應的角色和權限,交給shiro管理
23      *     調用時機:在需要訪問資源的時候,需要角色和權限的視乎才會調用此方法
24      * @param principalCollection
25      * @return
26      */
27     @Override
28     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
29 
30         System.out.println("已登陸成功,授予登錄用戶權限,也就是賦予用戶對應的角色和能夠訪問的菜單");
31 
32         //1.獲取當前登錄的用戶對象
33         SysUsers sysUSers = (SysUsers) principalCollection.getPrimaryPrincipal();
34 
35         //2.獲取當前登錄用戶的 用戶id
36         int uid = sysUSers.getId();
37 
38         //3.根據用戶id,查詢數據庫中這個用戶對應的角色集合和權限集合
39         Set<String> roleList = roleService.findRoleListByUid(uid);
40         Set<String> menuList = menuService.findMenuListbyUid(uid);
41 
42         //4.創建shiro中的用戶權限對象
43         SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo();
44 
45         //5.將查詢到的角色集合放入shiro的權限對象
46         auth.setRoles(roleList);
47 
48         //6.將查詢到的權限集合放入shiro的權限對象
49         auth.setStringPermissions(menuList);
50 
51         //7.返回shiro權限對象
52         return auth;
53     }
54 
55     /**
56      *     根據用戶在頁面輸入的用戶名,查詢數據庫中的用戶名和密碼,交給shiro框架
57      *     讓shiro框架進行對比用戶名,密碼是否正確
58      *    調用時機:在controller調用subject.login(token);方法就會執行這個方法,進行用戶名 密碼校驗
59      * @param auth
60      * @return
61      * @throws AuthenticationException
62      */
63     @Override
64     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
65         System.out.println("開始校驗用戶名和密碼................");
66 
67         //1.獲取用戶在瀏覽器輸入的用戶名
68         String userName = (String) auth.getPrincipal();
69         //2.根據用戶輸入的用戶名,查詢數據庫的用戶對象
70         String password = new String((char[]) auth.getCredentials());
71         //3.判斷用戶是否為空,為空則拋出異常
72         SysUsers sysUSer = userService.findUserbyName(userName);
73         if (sysUSer == null) {
74             throw new UnknownAccountException("賬號不存在,請先注冊,再登錄!");
75         }
76         //4.對比數據庫的密碼和用戶輸入的密碼是否一致
77         if(!password.equals(sysUSer.getPassword())){
78             throw new IncorrectCredentialsException("密碼錯誤");
79         }
80         //5.判斷用戶狀態,1正常,其他為鎖定狀態
81         if(sysUSer.getStatus() != 1){
82             throw new LockedAccountException("賬號被鎖定不允許登錄");
83         }
84         //6.封裝shiro中需要的權限對象,包括用戶名 密碼 以及當前用戶對象交給shiro返回
85         SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userName, password, this.getName());
86         return info;
87     }
88 }

其他Controller方法需要做權限驗證時,可以在上面加注解@RequiresPermissions("sys:product:add")

括號里是權限字符串,用冒號連接

shiro注解用在Service和Controller層,但是如果Service層有事務注解,那么shiro注解要放在Controller層。因為兩個代理對象在類型轉換時會出現異常。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM