1. 程式人生 > >shiro實現許可權管理時遇到的坑

shiro實現許可權管理時遇到的坑

最近在一個專案中應用到了shiro框架實現許可權管理,也是一邊在網上查資料一邊實現,對shiro的細節的李姐可能不夠深入,所以都在專案中遇到了挺多麻煩。現在說一下我遇到的情況

//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;
}
上面是我配置的自定義的realm。執行發現能夠進入到自定義的realm,但只能打印出“2222”及以上的部分,queryUserByLoginName方法以下的都無法執行的到,但很奇怪的是後臺還不報錯,還可以繼續執行其他相關程式。

在網上查找了很長時間,發現網上有很多說是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);
如果網友有更好的方式,麻煩指點一二