@Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 從 principals獲取主身份信息 // 將getPrimaryPrincipal方法返回值轉爲真實身份類型(在上邊的doGetAuthenticationInfo認證經過填充到SimpleAuthenticationInfo中身份類型), ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal(); // 根據身份信息獲取權限信息 // 從數據庫獲取到權限數據 List<SysPermission> permissionList = null; try { permissionList = sysService.findPermissionListByUserId(activeUser.getUserid()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // 單獨定一個集合對象 List<String> permissions = new ArrayList<String>(); if (permissionList != null) { for (SysPermission sysPermission : permissionList) { // 將數據庫中的權限標籤 符放入集合 permissions.add(sysPermission.getPercode()); } } // 查到權限數據,返回受權信息(要包括 上邊的permissions) SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); // 將上邊查詢到受權信息填充到simpleAuthorizationInfo對象中 simpleAuthorizationInfo.addStringPermissions(permissions); return simpleAuthorizationInfo; }
解釋:訪問上面這個須要有item:edit權限。html
在springmvc.xml中配置: java
<!-- 開啓aop,對類代理 --> <aop:config proxy-target-class="true"></aop:config> <!-- 開啓shiro註解支持 --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean>
Jsp頁面添加:spring
<%@ tagliburi="http://shiro.apache.org/tags" prefix="shiro" %>數據庫
標籤名稱apache |
標籤條件(均是顯示標籤內容)session |
<shiro:authenticated>mvc |
登陸以後app |
<shiro:notAuthenticated>jsp |
不在登陸狀態時ide |
<shiro:guest> |
用戶在沒有RememberMe時 |
<shiro:user> |
用戶在RememberMe時 |
<shiro:hasAnyRoles name="abc,123" > |
在有abc或者123角色時 |
<shiro:hasRole name="abc"> |
擁有角色abc |
<shiro:lacksRole name="abc"> |
沒有角色abc |
<shiro:hasPermission name="abc"> |
擁有權限資源abc |
<shiro:lacksPermission name="abc"> |
沒有abc權限資源 |
<shiro:principal> |
顯示用戶身份名稱 |
<shiro:principal property="username"/> 顯示用戶身份中的屬性值
當調用controller的一個方法,因爲該 方法加了@RequiresPermissions("item:query") ,shiro調用realm獲取數據庫中的權限信息,看"item:query"是否在權限數據中存在,若是不存在就拒絕訪問,若是存在就受權經過。
當展現一個jsp頁面時,頁面中若是遇到<shiro:hasPermission name="item:update">,shiro調用realm獲取數據庫中的權限信息,看item:update是否在權限數據中存在,若是不存在就拒絕訪問,若是存在就受權經過。
還有一種狀況是有時候鏈接是在Ajax請求以後拼接到頁面的,有時候也須要根據權限進行判斷,項目中也遇到這種狀況:
思路:在頁面中定義一個JS全局變量,在shiro權限標籤裏面,若是有權限修改全局變量的值,在JS中根據全局變量的值判斷是否有權限
(1)頁面定義全局變量
<script>
var hasOperatingDepart=false;
<script>
(2)頁面用shiro標籤判斷是否有權限:(有權限會執行JS腳本改變全局變量的值)
<shiro:hasPermission name="department:operating"> <script> hasOperatingDepart = true; </script> </shiro:hasPermission>
(3)JS拼接的時候根據全局變量判斷是否有權限:
// 有刪除修改權限就顯示鏈接 if (hasOperatingDepart) { str += '<a onclick="updateDepartment(this)" class="el_delButton">修改</a> '; } else { str += "-"; }
有時候咱們須要在代碼中判斷用戶是否有某些權限;
// 獲取用戶信息 Subject currentUser = SecurityUtils.getSubject(); boolean permitted = currentUser.isPermitted("exammanager:factory");// 判斷是否有全廠管理的權限,有就不添加部門ID,沒有就設爲當前Session中的部門ID String departmentId = permitted ? null : departmentIdSession;
有時候咱們須要在代碼中判斷用戶是否有某些角色:
// 獲取用戶信息 Subject currentUser = SecurityUtils.getSubject(); boolean hasRole = currentUser.hasRole("教研室"); boolean hasRole2 = currentUser.hasRole("院長")
上面獲取的主體的權限碼是咱們在受權的時候塞進去的,固然咱們也能夠將角色碼也塞進去:
package cn.xm.jwxt.shiro; import cn.xm.jwxt.bean.system.Permission; import cn.xm.jwxt.bean.system.User; import cn.xm.jwxt.service.system.UserService; import cn.xm.jwxt.utils.ValidateCheck; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; import java.util.HashSet; import java.util.List; import java.util.Set; /** * @Author: qlq * @Description 自定義realm。根據上面傳下來的token去數據庫查信息,查到返回一個SimpleAuthenticationInfo,查不到返回null(用於shiro認證) * @Date: 21:56 2018/5/6 */ public class CustomRealm extends AuthorizingRealm { @Autowired private UserService userService; // 設置realm的名稱 @Override public void setName(String name) { super.setName("customRealm"); } // realm的認證方法,從數據庫查詢用戶信息 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String userCode=(String)token.getPrincipal();//獲取token的主身份(登陸的username User user = null; try { user = userService.getUserByUserCode(userCode); } catch (Exception e) { e.printStackTrace(); } AuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(user, user.getPassword(), this.getName()); return authenticationInfo; } // 用於受權 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //0.下面方法principals.getPrimaryPrincipal()獲取的是在上面認證的時候裝進AuthenticationInfo的對象 String userId=((User)(principals.getPrimaryPrincipal())).getUserid(); SimpleAuthorizationInfo simpleAuthorizationInfo=null; try { simpleAuthorizationInfo = new SimpleAuthorizationInfo(); //1.設置全部的權限(注意權限是以字符串的形式保存的權限碼) List<Permission> permissions1 = userService.selectPermissionsByUserId(userId);//獲取全部權限碼 Set<String> permissions = new HashSet<>(); for(Permission permission:permissions1){ if(ValidateCheck.isNotNull(permission.getPermissioncode())){ permissions.add(permission.getPermissioncode()); } } if (permissions != null && permissions.size()>0) { simpleAuthorizationInfo.setStringPermissions(permissions); } //2.設置角色,角色也是以字符串的形式表示(這裏存的是角色名字) Set<String> userRoleNames = userService.getUserRoleNameByUserId(userId); if(userRoleNames != null && userRoleNames.size()>0){ simpleAuthorizationInfo.setRoles(userRoleNames); } } catch (Exception e) { e.printStackTrace(); } return simpleAuthorizationInfo; } }
獲取用戶信息
@RequestMapping("/first.action") public String first(Model model)throws Exception{ //從shiro的session中取activeUser Subject subject = SecurityUtils.getSubject(); //取身份信息 ActiveUser activeUser = (ActiveUser) subject.getPrincipal(); //經過model傳到頁面 model.addAttribute("activeUser", activeUser); return "/first"; }