shiro實現許可權管理時遇到的坑
阿新 • • 發佈:2019-02-10
最近在一個專案中應用到了shiro框架實現許可權管理,也是一邊在網上查資料一邊實現,對shiro的細節的李姐可能不夠深入,所以都在專案中遇到了挺多麻煩。現在說一下我遇到的情況
上面是我配置的自定義的realm。執行發現能夠進入到自定義的realm,但只能打印出“2222”及以上的部分,queryUserByLoginName方法以下的都無法執行的到,但很奇怪的是後臺還不報錯,還可以繼續執行其他相關程式。//1. 把 AuthenticationToken 轉換為 UsernamePasswordToken UsernamePasswordToken upToken = (UsernamePasswordToken) token; //2. 從 UsernamePasswordToken 中來獲取 username String username = upToken.getUsername(); System.out.println("doGetAuthenticationInfo---username:"+username); //3. 呼叫資料庫的方法, 從資料庫中查詢 username 對應的使用者記錄 System.out.println("2222"); TManagerUser managerUser = sysUserManagerService.queryUserByLoginName(username); System.out.println("3333"); System.out.println("doGetAuthenticationInfo---managerUser:"+JSONObject.toJSON(managerUser)); //4. 若使用者不存在, 則可以丟擲 UnknownAccountException 異常 System.out.println("1111"); if(managerUser==null){ throw new UnknownAccountException("使用者不存在!"); }else { //5. 根據使用者資訊的情況, 決定是否需要丟擲其他的 AuthenticationException 異常. if("locked".equals(managerUser.getUserStatus())){ throw new LockedAccountException("使用者被鎖定"); } //6. 根據使用者的情況, 來構建 AuthenticationInfo 物件並返回. 通常使用的實現類為: SimpleAuthenticationInfo //以下資訊是從資料庫中獲取的. //1). principal: 認證的實體資訊. 可以是 username, 也可以是資料表對應的使用者的實體類物件. Object principal = username; //2). credentials: 密碼. Object credentials = managerUser.getUserPassword(); System.out.println("credentials:"+credentials); //3). realmName: 當前 realm 物件的 name. 呼叫父類的 getName() 方法即可 String realmName = getName(); //4). 鹽值. 將使用者名稱作為鹽 ByteSource credentialsSalt = ByteSource.Util.bytes(username); SimpleAuthenticationInfo info = null; //new SimpleAuthenticationInfo(principal, credentials, realmName); info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName); System.out.println("info:"+JSONObject.toJSON(info)); return info; }
在網上查找了很長時間,發現網上有很多說是service未能正常引入的問題。所以我就在service方法中添加了try-catch程式碼,後來發現他會抓取到空指標異常。如下圖:
接下來就根據這個提示解決問題。該專案是由ssm框架搭建的,所以結合網上的提示,想到是不是因為service沒有在realm之前引入。結果在spring的相關配置檔案引入相關配置還是沒有實現(本人小白,剛工作不久,對spring理解及應用不是很熟悉,希望有大神指點一二)。最後通過一個很笨的方法實現了,就是替換service的queryUserByLoginName方法。將其改為下面的程式碼實現即可
如果網友有更好的方式,麻煩指點一二SqlSession openSession = sqlSessionFactory.openSession(); TManagerUserMapper userMapper = openSession.getMapper(TManagerUserMapper.class); TManagerUserExample example = new TManagerUserExample(); example.createCriteria().andUserLoginNameEqualTo(username); List<TManagerUser> managerUsers = userMapper.selectByExample(example);