在实际项目中,每一个用户角色登录进系统看到的菜单可能会不一样,这样就涉及到了用户权限的问题,Shiro也是目前常用的权限框架。
一、授权方式
shiro支持三种授权方式:
1、编程式(基本不用):通过写if/else授权代码块完成。
2、注解式:通过在执行的Java方法上防止相应的注解完成,没有权限将抛出相应的异常。
3、JSP标签:在JSP页面通过相应的标签完成。
二、默认拦截器
1、rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。
2、port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
3、perms:例子/admins/user/**=perms[user:add:*],perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
4、roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
5、anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
6、authc:例如/admins/user/**=authc表示需要认证才能使用,没有参数
7、authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
8、ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
9、user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
这些过滤器分为两组,一组是认证过滤器,一组是授权过滤器。其中anon,authcBasic,auchc,user是第一组,
perms,roles,ssl,rest,port是第二组。
三、Shiro标签
使用shiro标签之前要在jsp中引入标签库
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>
shiro的几种标签:
shiro:guest:用户没有身份验证时显示的信息 ,即游客访问信息
shiro:user:用户登陆后显示的信息,通过RememberMe认证通过
shiro:principal:显示用户身份信息
shiro:authenticated:用户已经身份验证通过,即通过Subject.login登录成功,不是RememberMe登录的
shiro:notAuthenticated:用户未进行身份验证,即没有通过Subject.login登录,包括RememberMe自动登录的也属于未进行身份验证
shiro:hasRole name="admin":如果当前Subject有角色,将显示body体内容
shiro:hasAnyRoles name="admin,user":只要有body体内有任意一个角色,就会显示里面的内容
shiro:lacksRole name="admin":如果当前的Subject没有角色将显示标签内内容
shiro:hasPermission name="user:create":如果当前Subject有权限就显示标签里的内容
shiro:lacksPermission name="org:create":如果当前Subject没有权限将显示标签里的内容
四、权限注解
权限注解可以用在service和controller层
1、@RequiresAuthentication:表示当前Subject已经通过login进行了身份验证;即Subject.isAuthenticated()返回true
2、@RequiresUser:表示当前Subject已经身份验证或者通过RemmberMe登录的
3、@RequiresGuest:表示当前Subject没有身份验证或通过RemmberMe登录过,即游客身份
4、@RequiresRole(value={"admin","user"},logical=Logical.AND):表示当前Subject需要角色admin和Uuser
5、RequiresPermissions(value={"user:a","user:b"},logical=Logical.OR):表示当前Subject需要权限user:a或user:b
五、具体实现
1、在web.xml中配置Spring、springmvc、shiro。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>shiro-2</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 1、配置Spring环境 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 2、配置SpringMVC环境 -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--
3、配置shiro 的 shiroFilter
DelegatingFilterProxy实际上是Filter的一个代理对象,默认情况下。
Spring会到IOC容器中查找和<filter-name>相应的filter bean。
也可以通过targetBeanName的初始化参数来配置filter bean 的id
-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2、配置springmvc配置文件:spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.spring