shiro實現登入和登出
阿新 • • 發佈:2019-02-20
shiro實現登入與登出
CustomRealm
public class CustomRealm extends AuthorizingRealm{
//設定realm的名稱
@Override
public void setName(String name) {
super.setName("customRealm");;
}
//用於認證
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// TODO Auto-generated method stub
//token是使用者輸入的
//第一步從token中取出身份資訊
String userCode = (String)token.getPrincipal();
//第二步:根據使用者輸入的userCode從資料庫查詢
//...
//模擬從資料庫查詢密碼
String password = "111111";
//如果查詢不到返回null
//資料庫中使用者賬號是zhangsan
if(!userCode.equals("zhangsan")) {
return null;
}
//如果查詢到返回認證資訊AuthenticationInfo
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, password,this.getName());
return simpleAuthenticationInfo;
}
//用於授權
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO Auto-generated method stub
//從principals獲取主身份資訊
//將getPrimaryPrincipal方法返回值轉為真實身份資訊(在上邊的doGetAuthecticationInfo認證通過填充到SimpleAuthenticationInfo)
String userCode = (String)principals.getPrimaryPrincipal();
//根據資訊獲取許可權資訊
//連線資料庫。。。
//模擬從資料庫獲取到資料
List<String> permissions = new ArrayList<String>();
permissions.add("user:create");
permissions.add("items:add");
//...
//查詢到許可權資料,返回
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//將上邊查詢到授權資訊填充到simpleAuthorizationInfo物件中
simpleAuthorizationInfo.addStringPermissions(permissions);
return simpleAuthorizationInfo;
}
}
登入:
原理:
使用FormAuthenticationFilter過濾器實現,原理如下:
將使用者沒有認證時,請求loginUrl進行認證,使用者身份和使用者密碼提交資料到loginurl,FormAuthenticationFilter攔截住取出request中的username和password(兩個引數名稱是可以配置的),
FormAuthenticationFilter呼叫realm傳入一個token(username和password),realm認證時根據username查詢使用者資訊(在Activeuser中儲存,包括……)如果查詢不到,realm返回null,FormAuthenticationFilter
向request域中填充一個引數(記錄了異常資訊)
/js/** = anon
……
controller程式碼
@RequestMapping("login")
public String login(HttpServletRequest request)throws Exception{
//如果登入失敗從request中獲取認證異常資訊,shiroLoginFailure就是shiro異常lei的全限定名
String shiroLoginFailure = request.getParameter("shiroLoginFailure");
//根據shiro返回的異常類路徑判斷,丟擲指定異常資訊
if (exceptionClassName!=null){
if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
//最終會拋給異常處理器
throw new CustomException("賬號不存在");
}else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
throw new CustomException("使用者名稱/密碼錯誤");
}else {
throw new Exception();//最終在異常處理器生成未知錯誤
}
}
//此方法不處理登入成功(認證成功),shiro認證成功會自動跳轉到上一個路徑
//登入失敗還到login
return "relogin";
}
登出
/logout = logout
- 注意:由於FormAuthenticationFilter的使用者身份和密碼的input的預設值(username和password),修改頁面的賬號和密碼的input的名稱為username和password