1. 程式人生 > >Shiro許可權框架之一 --------簡介

Shiro許可權框架之一 --------簡介

一. Shiro是什麼
Shiro是一個Java平臺的開源許可權框架,用於認證和訪問授權。具體來說,滿足對如下元素的支援:

  • 使用者,角色,許可權(僅僅是操作許可權,資料許可權必須與業務需求緊密結合),資源(url)。
  • 使用者分配角色,角色定義許可權。
  • 訪問授權時支援角色或者許可權,並且支援多級的許可權定義。

Q:對組的支援?
A:shiro預設不支援對組設定許可權。

Q:是否可以滿足對組進行角色分配的需求?
A:擴充套件Realm,可以支援對組進行分配角色,其實就是給該組下的所有使用者分配許可權。

Q:對資料許可權的支援? 在業務系統中定義?
A:shiro僅僅實現對操作許可權的控制,用於在前端控制元素隱藏或者顯示,以及對資源訪問許可權進行檢查。資料許可權與具體的業務需求緊密關聯,shiro本身無法實現對資料許可權的控制。

Q:動態許可權分配?
A:擴充套件org.apache.shiro.realm.Realm,支援動態許可權分配。

Q:與Spring整合?
A:可以支援與Spring整合,shiro還支援jsp標籤。


二. 系統架構

在shiro架構中,有3個最主要的元件:Subject,SecurityManager,Realm。
Subject本質上就是當前訪問使用者的抽象描述。
SecurityManager是Shiro架構中最核心的元件,通過它可以協調其他元件完成使用者認證和授權。實際上,SecurityManager就是Shiro框架的控制器。
Realm定義了訪問資料的方式,用來連線不同的資料來源,如:LDAP,關係資料庫,配置檔案等等。


三. 如何使用Shiro
Shiro作為一個完善的許可權框架,可以應用在多種需要進行身份認證和訪問授權的場景,例如:
1. 在獨立應用中使用shiro
http://www.cnblogs.com/nuccch/p/6780550.html 細說shiro之三:在獨立應用中使用shiro

2. 在web應用中使用shiro
http://www.cnblogs.com/nuccch/p/6785167.html 細說shiro之四:在web應用中使用shiro

3. 在spring框架中整合shiro
http://www.cnblogs.com/nuccch/p/6790408.html 細說shiro之五:在spring框架中整合shiro

四. Shiro原理
1. 認證
通過呼叫Subject.login(token)方法開始使用者認證流程。

複製程式碼

Subject currentUser = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
token.setRememberMe(true);
try {
  currentUser.login(token);
} catch (UnknownAccountException e) {
  logger.error(String.format("user not found: %s", username), e); // 使用者不存在
} catch (IncorrectCredentialsException e) {
  logger.error(String.format("incorrent credentials: %s", username), e); // 密碼不正確
} catch (ConcurrentAccessException e) {
  logger.error(String.format("user has been authenticated: %s", username), e); // 使用者重複登入
} catch (AccountException e) {
  logger.error(String.format("account except: %s", username), e); // 其他賬戶異常
}

複製程式碼

shiro使用者認證時序圖:

2. 授權
shiro訪問授權有3種實現方式:api呼叫,java註解,jsp標籤。
(1)在獨立應用程式中訪問授權通過api呼叫實現

複製程式碼

String role = "schwartz";
Subject currentUser = SecurityUtils.getSubject();
if(currentUser.hasRole(role)) {
  //使用者屬於角色schwartz
}else{
  //使用者不屬於角色schwartz
}

複製程式碼

(2)在spring框架中可以通過java註解

@RequiresPermissions(value={"log:manage:*"})
public ModelAndView home(HttpServletRequest req) {
  ModelAndView mv = new ModelAndView("home");
  return mv;
}

(3)在JSP頁面中還可以直接使用jsp標籤

<!-- 使用shiro標籤 -->
<shiro:hasPermission name="log:manage:*">
  <a href="<%=request.getContextPath()%>/user/home">操作日誌審計</a><br/>
</shiro:hasPermission>

shiro訪問授權時序圖:

五. 注意事項
1.org.apache.shiro.realm.jdbc.JdbcRealm如果需要在授權時開啟許可權檢查,必須設定permissionsLookupEnabled為true,否則只檢查角色。
2.使用者退出登入時,Shiro使用者必須執行logout(),必須要登出Session資訊,避免影響下一次使用者認證和授權。

SecurityUtils.getSubject().logout();
req.getSession().invalidate();

3.如果在資料庫中儲存的使用者密碼為編碼值(如MD5加密),則在傳送登入請求時傳遞的密碼引數也必須是MD5加密結果,否則認證失敗。
4.shiro框架只能控制操作許可權,不能控制資料許可權。資料許可權與具體的業務緊密關聯,無法通過一個通用的框架完成,通常都是利用關係資料庫查詢過濾實現。
對操作許可權的控制有2層含義,其一:使用者在前端只能看到對應許可權的元素;其二:在後端對使用者操作進行許可權檢查。