@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"; }