一、shiro授权角色、权限
shiro权限设计表:
Service
/** * 根据用户id查询角色(用于角色验证) * @param uid * @return */ Set<String> getRolesByUserId(Integer uid); /** * 根据用户id查询权限(用于权限判断) * @param uid * @return */ Set<String> getPersByUserId(Integer uid);
ShiroUserMapper.xml
<select id="getRolesByUserId" resultType="java.lang.String" parameterType="java.lang.Integer"> select r.roleid from t_shiro_user u,t_shiro_user_role ur,t_shiro_role r where u.userid = ur.userid and ur.roleid = r.roleid and u.userid = #{uid} </select> <select id="getPersByUserId" resultType="java.lang.String" parameterType="java.lang.Integer"> select p.permission from t_shiro_user u,t_shiro_user_role ur,t_shiro_role_permission rp,t_shiro_permission p where u.userid = ur.userid and ur.roleid = rp.roleid and rp.perid = p.perid and u.userid = #{uid} </select>
重写MyRealm中的授权方法
/** * 授权 * @param principals * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { ShiroUser shiroUser = this.shiroUserService.queryByName(principals.getPrimaryPrincipal().toString()); Set<String> roleids = this.shiroUserService.getRolesByUserId(shiroUser.getUserid()); Set<String> perIds = this.shiroUserService.getPersByUserId(shiroUser.getUserid()); SimpleAuthorizationInfo info =new SimpleAuthorizationInfo(); info.setRoles(roleids); info.setStringPermissions(perIds); return info; }
二、Shiro的注解式开发
常用注解介绍
@RequiresAuthenthentication:表示当前Subject已经通过login进行身份验证;即 Subject.isAuthenticated()返回 true
@RequiresUser:表示当前Subject已经身份验证或者通过记住我登录的
@RequiresGuest:表示当前Subject没有身份验证或者通过记住我登录过,即是游客身份
@RequiresRoles(value = {"admin","user"},logical = Logical.AND):表示当前Subject需要角色admin和user
@RequiresPermissions(value = {"user:delete","user:b"},logical = Logical.OR):表示当前Subject需要权限user:delete或者user:b
注解的使用
ShrioUserController
/** * 身份认证的注解 * @param shiroUser * @param req * @param resp * @return */ @RequestMapping("/passUser") public String passUser(ShiroUser shiroUser, HttpServletRequest req, HttpServletResponse resp) { return "admin/addUser"; } /** * 角色认证的注解 * @param shiroUser * @param req * @param resp * * 当前方法必须同时具备1、4的角色id,才能被访问 * @return */ @RequiresRoles(value = {"1","4"},logical = Logical.AND) @RequestMapping("/passRoles") public String passRoles(ShiroUser shiroUser, HttpServletRequest req, HttpServletResponse resp) { return "admin/listUser"; } /** * 权限认证的注解 * @param shiroUser * @param req * @param resp * @return */ @RequiresPermissions(value = {"user:update","user:view"},logical = Logical.OR) @RequestMapping("/passPer") public String passPer(ShiroUser shiroUser, HttpServletRequest req, HttpServletResponse resp) { return "admin/resetPwd"; } /** * 如果身份、角色、权限认证失败后的处理方式 * @param shiroUser * @param req * @param resp * @return */ @RequestMapping("/unauthorized") public String unauthorized(ShiroUser shiroUser, HttpServletRequest req, HttpServletResponse resp) { System.out.println("错误认证处理方案"); return "login"; }
在Springmvc-servlet.xml中添加
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true"></property> </bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean> <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthorizedException"> unauthorized </prop> </props> </property> <property name="defaultErrorView" value="unauthorized"/> </bean>
main.jsp
<ul> shiro注解 <li> <a href="${pageContext.request.contextPath}/passUser">身份认证</a> </li> <li> <a href="${pageContext.request.contextPath}/passRoles">角色认证</a> </li> <li> <a href="${pageContext.request.contextPath}/passPer">权限认证</a> </li> </ul>