一、概念
shiro是一个安全框架,主要可以帮助我们解决程序开发中认证和授权的问题。基于拦截器做的权限系统,权限控制的粒度有限,为了方便各种各样的常用的权限管理需求的实现,,我们有必要使用比较好的安全框架,早期spring security 作为一个比较完善的安全框架比较火,但是spring security学习成本比较高,于是就出现了shiro安全框架,学习成本降低了很多,而且基本的功能也比较完善。
二、shiro提供的功能
1、Authentication:身份认证/登陆,验证用户是不是拥有相对应的身份;
2、Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者粒度的验证某个用户对某个资源是否具有权限;
3、Session Manager:会话管理,即用户登陆后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是Web环境的;
4、Cryptographt:加密,保护数据,如密码加密存储到数据库,而不是明文存储;
5、Web Support:Web支持,可以非常容易的继承到Web环境的;
6、Caching:缓存,比如用户登陆后,其用户信息、拥有的角色/权限不必每次去查,这样提高效率;
7、Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
8、Testing:提供测试支持;
9、Run As:允许一个用户假装另一个用户(如果我们允许)的身份进行访问;
10、Remember Me:记住我,这个是非常常见的功能,即一次登陆后,下次再来的话不用登陆了。
三、shiro的架构
Subject:主题 被验证的对象,一般指的当前用户对象。但是不仅仅可以指当前用户对象,还可以是其他东西,线程等等。spring mvc中一个一个的用户的请求。
SecurityManager:安全认证管理器。是shiro的核心,会在安全认证管理器中所做所有的认证操作。类似于之前spring mvc中的前端控制器(DispacherServlet)。
Realm:域的意思。负责访问安全认证数据。shiro框架并不存在安全认证数据,安全认证数据需要用户自己存储。shiro支持很多的Realm实现,也就是说安全认证数据我们可以放到数据库中,也可以放到文件中等等。可以把realm理解为以前web项目的dao层。
四、shiro的认证
第一步,搭建框架 引入jar包
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 <groupId>aaa</groupId> 7 <artifactId>test_shiro_qy97_02</artifactId> 8 <version>1.0-SNAPSHOT</version> 9 <dependencies> 10 <dependency> 11 <groupId>commons-logging</groupId> 12 <artifactId>commons-logging</artifactId><version>1.0.4</version> 13 </dependency> 14 <dependency> 15 <groupId>org.apache.shiro</groupId> 16 <artifactId>shiro-core</artifactId> 17 <version>1.3.0</version> 18 </dependency> 19 <!-- 导入shiro和spring继承的jar包 --> 20 <dependency> 21 <groupId>org.apache.shiro</groupId> 22 <artifactId>shiro-spring</artifactId> 23 <version>1.2.3</version> 24 </dependency> 25 <!-- 导入shiro和web的jar包--> 26 <dependency> 27 <groupId>org.apache.shiro</groupId> 28 <artifactId>shiro-web</artifactId> 29 <version>1.2.3</version> 30 </dependency> 31 </dependencies> 32 </project>
第二步,在web.xml中声明shiro拦截权限的过滤器
1 <filter> 2 <filter-name>shiroFilter</filter-name> 3 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 4 <init-param> 5 <!--保证该过滤器的生命周期和spring 工厂中shiro过滤器对象的生命周期一致--> 6 <param-name>targetFilterLifecycle</param-name> 7 <param-value>true</param-value> 8 </init-param> 9 <!--声明该过滤器代理工厂类中的id为什么的shiro过滤器对象--><init-param> 10 <param-name>targetBeanName</param-name> 11 <param-value>shiroFilter</param-value> 12 </init-param> 13 </filter> 14 <filter-mapping> 15 <filter-name>shiroFilter</filter-name> 16 <url-pattern>/*</url-pattern> 17 </filter-mapping>
第三步,在spring的主配置文件汇总声明shiro的配置信息
shiro的配置信息比较多,一般不和spring的主配置文件放到一起,一般都会单独建立一个shiro和spring继承的配置文件,创建好之后,在spring.xml中引入该文件。
spring-shiro中配置:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 <!--创建自定义域对象--> 7 <bean id="authRealm" class="com.aaa.ssm.realm.AuthRealm"></bean> 8 <!--创建shiro的安全管理器对象--> 9 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 10 <!--要声明域,在域中读取认证和授权的数据--> 11 <property name="realm" ref="authRealm"></property> 12 </bean> 13 <!--创建shiro的过滤器对象--> 14 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 15 <!--要注入安全管理器对象--> 16 <property name="securityManager" ref="securityManager"></property> 17 <!--配置登录请求的路径--> 18 <property name="loginUrl" value="/user/login.do"></property> 19 <!--配置shiro认证和授权的过滤器--> 20 <property name="filterChainDefinitions"> 21 <value> 22 <!--对静态资源不拦截--> 23 <!--anon指匿名访问的过滤器,所有匿名用户都可以访问static下面的资源--> 24 /static/*=anon 25 /user/login.do=anon 26 /login.jsp=anon 27 <!--authc指必须经过认证(登录过之后)才能访问的请求 /*代表所有有一个斜杠的请求都要经过认证 --> 28 /*=authc 29 /*/*=authc 30 </value> 31 </property></bean> 32 </beans>
第四步,创建自定义域对象
1 package com.aaa.ssm.realm; 2 import com.aaa.ssm.entity.Users; 3 import com.aaa.ssm.service.UserService; 4 import org.apache.shiro.authc.*import org.apache.shiro.authz.AuthorizationInfo; 5 import org.apache.shiro.realm.AuthorizingRealm; 6 import org.apache.shiro.realm.Realm; 7 import org.apache.shiro.subject.PrincipalCollection; 8 import org.springframework.beans.factory.annotation.Autowired; 9 /** 10 * 实现自定义域 11 * Authorization 授权(权限校验) 12 * 13 * Authentication 认证(登录校验) 14 * 15 */ 16 public class AuthRealm extends AuthorizingRealm { 17 @Autowired 18 private UserService userService; 19 //获取授权信息 20 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 21 return null; 22 }//获取认证信息 23 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws 24 AuthenticationException { 25 //获取用户名 不过一般往shiro中放置用户身份信息的时候,不直接放用户名字符串,放用户对象 26 String username = token.getPrincipal().toString(); 27 //有了用户名,要根据用户名在数据库中查询用户对象 28 Users user = userService.findByUsername(username); 29 //判断如果用户对象不存在,抛出UnknownAccountException 30 if(user==null){ 31 throw new UnknownAccountException("用户名不存在"); 32 } 33 //封装用户的身份对象 返回这个身份对象 34 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),"authRealm"); 35 return info; 36 } 37 }
第五步,在控制器(Controller)中使用shiro去做登陆认证
1 /** 2 * 用户登录的请求 3 * @param user 4 * @return 5 */ 6 @RequestMapping("/login") 7 public String login(Users user, Model model, HttpSession session){ 8 /* user = userService.checkUser(user)//判断user是否为空 9 if(user!=null){ 10 //用户名和密码输入正确 11 //登录成功之后把用户对象放置到session中 12 //登录成功之后,查询用户能操作的模块 13 session.setAttribute(Constants.SESSION_USER,user); 14 List<Module> oneModules = userService.queryUsersModules(user); 15 //获取用户能操作的所有模块的路径,放置到session中 16 List<String> permiteUrls = userService.queryPermitUrls(oneModules); 17 session.setAttribute(Constants.PERMIT_URLS,permiteUrls); 18 model.addAttribute("oneModules",oneModules); 19 return "index"; 20 }else{ 21 return "redirect:/login.jsp"; 22 }*/ 23 //获取用户的主体对象就可以了 24 Subject subject = SecurityUtils.getSubject();//封装用户名和密码的认证信息对象 25 UsernamePasswordToken upt = new UsernamePasswordToken(user.getUsername(),user.getPassword()); 26 //进行登录认证 27 try { 28 subject.login(upt); 29 }catch (Exception e){ 30 e.printStackTrace(); 31 System.out.println("用户名或者密码错误"); 32 return "redirect:/login.jsp"; 33 } 34 return "index"; 35 }
五、密码加密
一般在数据库中存储明文的密码是不安全的,一般都会对项目中的密码进行加密。加密算法分为两大类,一类是可逆加密,另一类是不可逆加密。可逆加密分两类,一类是堆成加密,另外一类是非对称加密。一般对称加密的私钥在客户端和服务器端都是一致的。非对称加密私钥在客户端和服务器端是不一样的。非可逆加密,任何加密算法的安全性都要建立在你的源码已经被别人获取的情况下还算安全,那这种加密算法才算是成功的,这就是非可逆加密。常用的非可逆加密算法有MD5和SHA1,SHA256等等。
1 package com.aaa.ssm.util; 2 import org.apache.shiro.crypto.hash.SimpleHash; 3 /** 4 * 测试非可逆加密算法 5 */ 6 public class PasswordUtil { 7 public static void main(String[] args) { 8 String str = "123456"; 9 //第一个参数代表加密使用的算法 第二个参数要加密的字符串 第三个参数 加入的盐的值 第四个参数 hash迭代的次数 10 //以后再保存用户的密码应该使用加密算法加密 11 SimpleHash simpleHash = new SimpleHash("md5",str,"123",10); 12 String code = simpleHash.toString(); 13 System.out.println("加密后的密文:"+code); 14 } 15 }
密码加密存储之后,在使用shiro做校验,应该在realm中做如下配置:
1 <!--创建自定义域对象--> 2 <bean id="authRealm" class="com.aaa.ssm.realm.AuthRealm"> 3 <property name="credentialsMatcher" ref="credentialsMatcher"></property> 4 </bean> 5 <!-- 创建凭证匹配器对象--> 6 <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> 7 <!--指定要对用户传过来的明文的密码最什么加密--> 8 <property name="hashAlgorithmName" value="md5"></property> 9 <!--指明hash迭代的次数--> 10 <property name="hashIterations" value="10"></property> 11 </bean>
在自定义的realm中,传入用户密码对应的盐值:
1 package com.aaa.ssm.realm; 2 3 import com.aaa.ssm.entity.Module; 4 import com.aaa.ssm.entity.Users; 5 import com.aaa.ssm.service.IUserServiceDAO; 6 import org.apache.shiro.authc.*; 7 import org.apache.shiro.authz.AuthorizationInfo; 8 import org.apache.shiro.authz.SimpleAuthorizationInfo; 9 import org.apache.shiro.realm.AuthorizingRealm; 10 import org.apache.shiro.subject.PrincipalCollection; 11 import org.apache.shiro.util.ByteSource; 12 import org.springframework.beans.factory.annotation.Autowired; 13 14 import java.util.List; 15 16 /** 17 * 实现自定义域 18 * Authorization 授权(权限校验) 19 * 20 * Authentication 认证(登录校验) 21 * 22 */ 23 public class AuthRealm extends AuthorizingRealm { 24 25 @Autowired 26 private IUserServiceDAO userService; 27 //获取授权信息 28 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 29 //获取当前的用户对象 30 Users user = (Users) principalCollection.getPrimaryPrincipal(); 31 //查询用户有哪些权限 32 List<Module> modules = userService.userModule(user); 33 List<String> namespaces = userService.queryPrimaryUrl(modules); 34 //创建授权对象 35 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 36 //把用户能操作的资源的信息放置到授权对象中 37 info.addStringPermissions(namespaces); 38 return info; 39 } 40 41 //获取认证信息 42 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 43 Object pri = token.getPrincipal(); 44 if(pri==null){ 45 throw new UnknownAccountException("用户名为空"); 46 } 47 //获取用户名 不过一般往shiro中放置用户身份信息的时候,不直接放用户名字符串,放用户对象 48 String username = pri.toString(); 49 //有了用户名,要根据用户名在数据库中查询用户对象 50 Users user = userService.findByUsername(username); 51 //判断如果用户对象不存在,抛出UnknownAccountException 52 if(user==null){ 53 throw new UnknownAccountException("用户名不存在"); 54 } 55 //盐值一般每个用户是不一样的 56 ByteSource bytes = ByteSource.Util.bytes("123"); 57 //封装用户的身份对象 返回这个身份对象 58 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),bytes,"authRealm"); 59 return info; 60 } 61 }
六、授权(用户登陆之后能访问所有的请求)
1、配置文件的方式
xml的方式
第一步,在shiro的主配置文件中配置授权信息
1 <!--创建shiro的过滤器对象--> 2 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 3 <!--要注入安全管理器对象--> 4 <property name="securityManager" ref="securityManager"></property> 5 <!--配置登录请求的路径--> 6 <property name="loginUrl" value="/user/toLogin.do"></property> 7 <!--如果用户没有经过授权跳转到的错误界面--> 8 <property name="unauthorizedUrl" value="/error.jsp"></property> 9 <!--配置shiro认证和授权的过滤器--> 10 <property name="filterChainDefinitions"> 11 <value> 12 <!--对静态资源不拦截--> 13 <!--anon指匿名访问的过滤器,所有匿名用户都可以访问static下面的资源--> 14 /static/*=anon 15 /user/login.do=anon 16 <!--不拦截跳转到主界面的请求--> 17 /user/index.do=anon 18 <!--配置登出请求的过滤器--> 19 /user/logout.do=logout 20 <!--配置/user/list.do必须有user的权限才能访问--> 21 /user/list.do=anon 22 /role/*.do=perms[role] 23 <!--authc指必须经过认证(登录过之后)才能访问的请求 /*代表所有有一个斜杠的请求都要经过认证 --> 24 /*=authc 25 /*/*=authc 26 </value> 27 </property> 28 </bean>
第二步,当前登陆用户有哪些授权信息从自定义的realm中读取(
AuthorizationInfo)
1 package com.aaa.ssm.realm; 2 3 import com.aaa.ssm.entity.Module; 4 import com.aaa.ssm.entity.Users; 5 import com.aaa.ssm.service.IUserServiceDAO; 6 import org.apache.shiro.authc.*; 7 import org.apache.shiro.authz.AuthorizationInfo; 8 import org.apache.shiro.authz.SimpleAuthorizationInfo; 9 import org.apache.shiro.realm.AuthorizingRealm; 10 import org.apache.shiro.subject.PrincipalCollection; 11 import org.apache.shiro.util.ByteSource; 12 import org.springframework.beans.factory.annotation.Autowired; 13 14 import java.util.List; 15 16 /** 17 * 实现自定义域 18 * Authorization 授权(权限校验) 19 * 20 * Authentication 认证(登录校验) 21 * 22 */ 23 public class AuthRealm extends AuthorizingRealm { 24 25 @Autowired 26 private IUserServiceDAO userService; 27 //获取授权信息 28 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 29 //获取当前的用户对象 30 Users user = (Users) principalCollection.getPrimaryPrincipal(); 31 //查询用户有哪些权限 32 List<Module> modules = userService.userModule(user); 33 List<String> namespaces = userService.queryPrimaryUrl(modules); 34 //创建授权对象 35 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 36 //把用户能操作的资源的信息放置到授权对象中 37 info.addStringPermissions(namespaces); 38 return info; 39 } 40 41 //获取认证信息 42 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 43 Object pri = token.getPrincipal(); 44 if(pri==null){ 45 throw new UnknownAccountException("用户名为空"); 46 } 47 //获取用户名 不过一般往shiro中放置用户身份信息的时候,不直接放用户名字符串,放用户对象 48 String username = pri.toString(); 49 //有了用户名,要根据用户名在数据库中查询用户对象 50 Users user = userService.findByUsername(username); 51 //判断如果用户对象不存在,抛出UnknownAccountException 52 if(user==null){ 53 throw new UnknownAccountException("用户名不存在"); 54 } 55 //盐值一般每个用户是不一样的 56 ByteSource bytes = ByteSource.Util.bytes("123"); 57 //封装用户的身份对象 返回这个身份对象 58 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),bytes,"authRealm"); 59 return info; 60 } 61 }
2、注解的方式
第一步,开始spring的shiro的注解支持
注意,开启注解的支持之前,应该保证项目中有spring的aop的jar包,aspectj等的jar包
1 <dependency> 2 <groupId>org.springframework</groupId> 3 <artifactId>spring-aop</artifactId> 4 <version>${spring.version}</version</dependency> 5 <!-- aspectj相关jar包--> 6 <dependency> 7 <groupId>org.aspectj</groupId> 8 <artifactId>aspectjrt</artifactId> 9 <version>1.7.4</version></dependency> 10 <dependency> 11 <groupId>org.aspectj</groupId> 12 <artifactId>aspectjweaver</artifactId> 13 <version>1.7.4</version> 14 </dependency>
要在spring mvc的主配置文件中声明shiro的注解的支持:
1 <!--开启aop--> 2 <aop:config proxy-target-class="true"></aop:config> 3 <!--开启shiro的aop注解的支持--> 4 <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor" > 5 <property name="securityManager" ref="securityManager"></property> 6 </bean>
第二步,在控制器的代码中增加需要授权的注解
第三步,同xml的方式的第二步,配置当前登陆用户有哪些授权信息从自定义的realm中读取(
AuthorizationInfo)
第四步,声明spring mvc的统一异常处理
1 <!--声明spring mvc的统一异常处理界面--> 2 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 3 <property name="defaultErrorView" value="../../error"></property> 4 </bean>
七、shiro会话管理器
shiro中提供的类似于web中的session的机制
1 /** 2 * 跳转到系统管理的主界面 3 * @return 4 */ 5 @RequestMapping("/index") 6 public String index(Model model){ 7 //可以通过Subject获取shiro会话中的用户身份对象 8 Users user = (Users)SecurityUtils.getSubject().getPrincipal(); 9 List<Module> oneModules = userService.queryUsersModules(user); 10 model.addAttribute("oneModules",oneModules); 11 return "index"; 12 } 13 /** 14 * 用户登录的请求 15 * @param user 16 * @return 17 */ 18 @RequestMapping("/login") 19 public String login(Users user, Model model, HttpSession session){ 20 //获取用户的主体对象就可以了 21 Subject subject = SecurityUtils.getSubject(); 22 //封装用户名和密码的认证信息对象 23 UsernamePasswordToken upt = new UsernamePasswordToken(user.getUsername(),user.getPassword()); 24 //进行登录认证try { 25 subject.login(upt); 26 }catch (Exception e){ 27 e.printStackTrace(); 28 model.addAttribute("error","用户名或者密码错误"); 29 return "login"; 30 } 31 return "redirect:/user/index.do"; 32 }
tomcat的session可以控制超时时间,shiro的session也可以控制。如果需要控制类似于超时时间这些session的属性,就需要在shiro的主配置文件中配置sessionManager对象
1 <!--创建会话管理器对象--> 2 <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> 3 <!--配置session的超时时间,默认单位是毫秒--> 4 <property name="globalSessionTimeout" value="1000"></property> 5 </bean> 6 <!--创建shiro的安全管理器对象--> 7 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 8 <!--要声明域,在域中读取认证和授权的数据--> 9 <property name="realm" ref="authRealm"></property> 10 11 <!--声明会话管理器属性--> 12 <property name="sessionManager" ref="sessionManager" ></property> 13 14 <property name="rememberMeManager" ref="rememberMeManager"></property> 15 16 17 <!--<property name="cacheManager" ref="cacheManager"></property>--> 18 </bean>
八、登出
首先需要在用户登陆后的主界面写一个登出的连接
然后在控制器中实现登出的方法,注意在此方法中不用写任何逻辑
在shiro的主配置文件中配置,登出的请求经过的过滤器就可以,在shiro的过滤器中有一个名称为logout的过滤器专门为我们处理登出请求:
1 <!--配置shiro认证和授权的过滤器--> 2 <property name="filterChainDefinitions"> 3 <value> 4 <!--对静态资源不拦截--> 5 <!--anon指匿名访问的过滤器,所有匿名用户都可以访问static下面的资源--> 6 /static/*=anon 7 /user/login.do=anon 8 <!--不拦截跳转到主界面的请求--> 9 /user/index.do=anon 10 <!--配置登出请求的过滤器--> 11 /user/logout.do=logout 12 <!--配置/user/list.do必须有user的权限才能访问--> 13 /user/list.do=anon 14 /role/*.do=perms[role] 15 <!--authc指必须经过认证(登录过之后)才能访问的请求 /*代表所有有一个斜杠的请求都要经过认证 --> 16 /*=authc 17 /*/*=authc 18 </value> 19 </property>
九、Remember Me 记住我
第一步,首先在登陆界面声明“记住我”的复选框
第二步,在控制器中,接收rememberMe的参数:
第三步,在shiro主配置文件中实现记住我的功能:
十、shiro标签库的使用
shiro为我们提供了一些简单的标签可以在jsp中使用,可以用来控制用户权限做一些操作
第一步,使用标签库,首先导入shiro的标签库:
第二步,写所需要的标签
shiro常用标签:
guest标签:验证当前用户是否为“访客”,即未认证(包含未记住)的用户
1 <shiro:guest> 2 3 Hi there! Please <a href="login.jsp">Login</a> or <a href="signup.jsp">Signup</a> today! 4 5 </shiro:guest>
user标签:认证通过或者已记住的用户
1 <shiro:user> 2 3 Welcome back John! Not John? Click <a href="login.jsp">here<a> to login. 4 5 </shiro:user>
authenticated标签:已认证通过的用户。不包含已记住的用户,这是与user标签的区别
1 <shiro:authenticated> 2 3 <a href="updateAccount.jsp">Update your contact information</a>. 4 5 </shiro:authenticated>
noAuthenticated标签:未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户
1 <shiro:notAuthenticated> 2 3 Please <a href="login.jsp">login</a> in order to update your credit card information. 4 5 </shiro:notAuthenticated>
principal标签:输出当前用户信息,通常为登陆账号信息
1 Hello, <shiro:principal/>, how are you today?
hashRole标签:验证当前用户是否属于该角色
1 <shiro:hasRole name="administrator"> 2 3 <a href="admin.jsp">Administer the system</a> 4 5 </shiro:hasRole>
lackRole标签:与hasRole标签逻辑相反,当用户不输入该角色时验证通过
1 <shiro:lacksRole name="administrator"> 2 3 Sorry, you are not allowed to administer the system. 4 5 </shiro:lacksRole>
hasAnyRole标签:验证当前用户是否属于以下任意一个角色
1 <shiro:hasAnyRoles name="developer, project manager, administrator"> 2 3 You are either a developer, project manager, or administrator. 4 5 </shiro:hasAnyRoles>
hasPermission标签:验证当前用户是否拥有指定权限
1 <shiro:hasPermission name="user:create"> 2 3 <a href="createUser.jsp">Create a new User</a> 4 5 </shiro:hasPermission>
lacksPermission标签:与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过
1 <shiro:lacksPermission name="user:create"> 2 3 <a href="createUser.jsp">Create a new User</a> 4 5 </shiro:lacksPermission>