本系列博文目錄:http://www.javashuo.com/article/p-ewndobct-kn.htmlhtml
shiro受權的操做主要分爲兩個步驟java
一、匹配登陸用戶的角色,並將權限賦予當前用戶所建立的Subject。git
二、訪問某一資源時,從當前用戶Subject中取得權限並驗證是否能夠訪問這個資源。github
shiro自己並不提供權限管理的機制,權限的管理須要咱們本身進行維護。常見的作法是在數據庫建立用戶、角色和權限表進行管理。數據結構相似於下圖數據庫
權限的標識符(代碼中匹配權限的字符串)理論上能夠自由定義,可是通常狀況咱們會賦予含義。apache
例如:「company_add「或「company:add」。前面表明模塊後面表明功能。數據結構
當一個用戶成功登錄後,咱們會先取得用戶的userId,而後去數據庫中找到對應的角色以及下面的全部權限。最後將這些權限存入當前用戶的權限信息中,以便訪問資源時使用這些權限進行比對。app
賦予權限時咱們要繼承AuthorizingRealm類,並實現doGetAuthorizationInfo抽象方法。ide
/** * 受權 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //獲取當前登陸用戶的信息(登陸認證時取得的) Principal principal = (Principal) principals.getPrimaryPrincipal(); //使用登陸信息中存入的userId獲取當前用戶全部權限 List<String> authorities = getAuthority(principal.getUserId()); //建立受權信息類 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); //將權限存入受權信息類 authorizationInfo.addStringPermissions(authorities); return authorizationInfo; }
shiro支持經過四種方式進行權限驗證。ui
一、代碼判斷(代碼級)
使用subject.isPermitted( )方法,驗證是否有權限,後進行對應的處理。驗證失敗邏輯本身實現。
if(SecurityUtils.getSubject().isPermitted("admin_home")){ System.out.println("我有這個權限"); }else{ System.out.println("我沒有這個權限"); }
二、使用註解(方法級)
註解方式屬於方法級的權限控制。使用@RequiresPermissions註解的方法時會驗證權限。驗證失敗拋出org.apache.shiro.authz.AuthorizationException異常。
@RequiresPermissions("admin_home") @RequestMapping(value="/index", method = RequestMethod.GET) public String index(ModelMap model){ System.out.println("我有這個權限"); }
三、使用標籤(頁面元素級)
使用標籤屬於頁面元素及的權限控制。訪問被標籤控制的頁面元素時,須要擁有標籤指定的權限。驗證失敗的的內容在頁面上是隱藏的。
這裏須要注意freemaker是不能直接使用shiro權限驗證標籤的,若是要使用須要引入shiro-freemarker-tags包,具體方法請參考另外一篇博文《Shiro快速入門 —— 9.freemaker使用shiro標籤》。
<!-- 驗證單個權限 --> <@shiro.hasPermission name = "admin_company_manage"> <!-- 被控制的頁面元素 --> </@shiro.hasPermission> <!-- 驗證多個權限是能夠在外層嵌套循環,只要擁有其中一個權限就顯示標籤 --> <#list ["admin1","admin2","admin3"] as permission> <@shiro.hasPermission name = permission> <!-- 被控制的頁面元素 --> </@shiro.hasPermission> </#list>
四、攔截器(路徑級)
在攔截器攔截路徑配置時,能夠指定權限攔截器和所需的權限。當訪問此路徑時進行權限驗證。驗證失敗會訪問在攔截器工廠類中配置的無權限提示頁。具體方法能夠參考《Shiro快速入門 —— 2.攔截器》
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); filterChainDefinitionMap.put("/home1/**", "perms[admin1]"); filterChainDefinitionMap.put("/home2/**", "perms[admin2]"); filterChainDefinitionMap.put("/home3/**", "perms[admin3]"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);//設置攔截規則
攔截器工廠類中配置無權限提示頁。具體方法能夠參考《Shiro快速入門 —— 2.攔截器》
shiroFilterFactoryBean.setUnauthorizedUrl("/common/unauthorized");//配置沒有權限跳轉的頁面