授權流程
- 首先調用Subject.isPermitted*/hasRole*接口,其會委託給SecurityManager,而SecurityManager接着會委託給Authorizer
- Authorizer是真正的授權者,如果我們調用如isPermitted(“user:view”),其首先會通過PermissionResolver把字符串轉換成相應的Permission實例
- 在進行授權之前,其會調用相應的Realm獲取Subject相應的角色/權限用於匹配傳入的角色/權限
- Authorizer會判斷Realm的角色/權限是否和傳入的匹配,如果有多個Realm,會委託給ModularRealmAuthorizer進行循環判斷,如果匹配如isPermitted*/hasRole*會返回true,否則返回false表示授權失敗
ModularRealmAuthorizer進行多Relam匹配流程:
+ 首先檢查相應的Realm是否實現了Authorizer
+ 如果實現了Authorizer,那麼接着調用其相應的isPermitted*/hasRole*接口進行匹配
+ 如果有一個Realm匹配,那麼將返回true,否則返回false
如果Realm進行授權的話,應該繼承AuthorizingRealm,其流程是:
+ 如果調用hasRole*,則直接獲取AuthorizationInfo.getRoles()與傳入的角色比較即可
+ 首先如果調用如isPermitted(“user:view”),首先通過PermittedResolver將權限字符串轉換成相應的Permission實例,默認使用WildcardPermissionResolver,即轉換爲通配符的WildcardPermission;
+ 通過AuthorizationInfo.getObjectPermissions()得到Permission實例整合;通過AuthorizationInfo.getStringPermisions()得到字符串集合並通過PermissionResolver解析爲Permission實例;然後獲取用戶的角色,並通過RolePermissionResolver解析角色對應的權限集合(默認沒有實現,可以自己提供)
+ 接着調用Permission.implies(Permission p)逐個與傳入的權限比較,如果有匹配的則返回true,否則false
與Web集成
過濾器DelegatingFilterProxy的作用是自動到spring容器查找名字爲shiroFilter(filter-name)的bean,並把所有Filter的操作委託給它。然後將ShiroFilter配置到Spring容器即可
ini配置
urls配置
格式是:url=攔截器[參數],攔截器[參數]
anon表示匿名訪問,即不需要登錄即可訪問
authc攔截器表示需要身份認證通過後才能訪問
roles[admin]攔截器表示需要有admin角色授權才能訪問
perms[“user:create”]攔截器表示需要有”user:create”權限才能訪問
url模式使用Ant風格模式,Ant路徑通配符支持?, *, **,注意通配符匹配不包括目錄分隔符/
+ ? 匹配一個字符
+ * 匹配零個或多個字符串
+ ** 匹配路徑中的零個或多個路徑
JSP標籤
- 導入標籤庫
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
- guest標籤,用戶沒有身份驗證時顯示相應信息,即遊客訪問信息
<shiro:guest>
Welcome !! <a href="${pageContext.request.contextPath}/login.jsp">登錄</a>
</shiro:guest>
- user標籤,用戶已經身份驗證/記住我登錄後顯示相應的信息
<shiro:user>
Welcome [<shiro:principal/>]登錄,<a href="${pageContext.request.contextPath}/logout.jsp">退出</a>
</shiro:user>
- authenticated標籤,用戶已經身份驗證通過,即Subject.login登錄成功,不是記住我登錄的
<shiro:authenticated>
用戶[<shiro:principal>]已身份認證通過
</shiro:authenticated>
- notAuenticated標籤,用戶已經身份驗證通過,即沒有調用Subject.login登錄,包括記住我自動登錄的也屬於未進身份驗證
<shiro:notAuthenticated>
未身份認證(包括記住我)
</shiro:notAuthenticated>
- principal標籤,顯示用戶身份信息,默認調用Subject.getPrincipal()獲取
<shiro:principal/>
<!-- 顯示用戶身份,默認調用Subject.getPrincipal()獲取,即Primary Principal -->
<shiro:principal type="java.lang.String"/>
<shiro:principal property="username"/>
- hasRole標籤,如果當前Subject有角色將顯示body內容
<shiro:hasRole name="admin">
用戶[<shiro:principal/>]擁有角色admin<br/>
</shiro:hasRole>
- hasAnyRoles標籤,如果當前Subject有任意一個角色(或的關係)將顯示body體內容
<shiro:hasAnyRoles name="admin, user">
用戶[<shiro:principal/>]擁有角色admin或user <br/>
</shiro:hasAnyRoles>
- lacksRole標籤,如果當前Subject沒有角色將顯示body體內容
<shiro:lacksRole name="abc">
用戶[<shiro:principal/>]沒有角色abc <br/>
</shiro:lacksRole>
- lacksPermission標籤,如果當前Subject沒有權限將顯示body體內容
<shiro:lacksPermission name="org:create">
用戶[<shiro:principal/>]沒有權限org:create <br/>
</shrio:lacksPermission>
Spring註解
@RequiresAuthentication
表示當前Subject已經通過login進行了身份認證,即Subject.isAuthenticated()返回true@RequiresUser
表示當前Subject已經身份驗證或者通過記住我登錄的@RequiresGuest
表示當前Subject沒有身份驗證或通過記住我登錄過,即是遊客身份@RequiresRoles(value={“admin”, “user”}, logical=Logical.AND)
表示當前Subject需要角色admin和user@RequiresPermissions(value={“user:a”, “user:b”}, logical=Logical.OR)
表示當前Subject需要權限user:a或user:b