史上最详细的shiro笔记

shiro笔记

shiro的基本概念

  • application code: 应用程序代码,代表的一个shiro的启动入口,用shiro的api来启动,可以理解成把用户的数据用shiro的api传递个shiro,由shiro来处理用户数据。
  • subject: 原意是主体,每一个subject代表每一个subject代表的一个用户,抽象的用户,就是用shiro对用户传来的数据进行封装,把数据封给token(令牌),最终可以狭义理解为数据。
  • securitymanager: 安全管理中心,是shiro的核心, 所有的数据都要经过shiro的安全管理中心。
  • realm:域,可以理解为数据的源头,可以是数据库,文件等。

shiro的原理

  • shiro的登录认证
    • 用户登录成功就可以访问敏感资源
    • 之后的所有访问都通过shiro直接访问指定的资源
    • 如果没有登录成功,跳转到指定的登录页面
    public Object around(ProceedJoinPoint pjp){
        Object returnValue = null;
        try{
            if(登录过){
                returnValue = pjp.proceed();
            }else{
                // 由shiro控制跳转到指定的页面,由pring-shiro.xml提供跳转的
            }
        }
    }
    // 注意:没有shiro项目的功能照样跑起来,添加shiro实际就是横切,把shiro横切
    // 实际是代理模式
    
  • shiro的权限认证
    • 在登录认证完成之后,根据用户的权限显示不同的菜单项

shiro项目的搭建步骤

  1. 创建项目
  2. 导入jar
    • 手动导入
    • maven导入
    <!-- Apache Shiro依赖 -->
    <dependency>
    	<groupId>org.apache.shiro</groupId>
    	<artifactId>shiro-all</artifactId>
    	<version>1.2.3</version>
    </dependency>
    
  3. 把shiro的对象交给spring容器来管理
    • spring-shiro.xml(名字任意)
    • web.xml
      • 添加shiro的过滤器,要用这个过滤器过滤所有的url
      • 配置所有的shiro的安全管理中心的对象
      • 配置shiro的过滤器对象
      • 配置登录和权限认证的对象
  4. 创建java类,实现相应接口

Shiro之HelloWorld

/**
 * 用ini文件模拟数据库,测试Shiro的认证
 */
public class ShiroTest {

    @Test
    public void testLogin() throws Exception{
        // 1. 创建securityManager工厂对象:加载配置文件,创建工厂对象
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        // 2. 通过工厂对象,创建SecurityManager对象
        SecurityManager securityManager =  factory.getInstance();
        // 3. 将securityManager绑定到当前运行环境中,让系统随时随地都可以访问该对象
        SecurityUtils.setSecurityManager(securityManager);
        // 4. 创建当前登录的主体,注意,此时主体没有经过认证
        Subject subject = SecurityUtils.getSubject();
        // 5. 收集主体登录的身份/凭证,即账号密码
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "666");
        // 6. 主体登录
        subject.login(token);
        // 7. 判断登录是否成功, 成功返回true,失败返回false
        System.out.println("验证登录是否成功:" + subject.isAuthenticated());
        // 8. 注销
        subject.logout();
        System.out.println("验证是否登录成功(退出之后返回false):" + subject.isAuthenticated());
    }
}
运行结果:
验证登录是否成功:true
验证是否登录成功(退出之后返回false)false
  • login方法可能会抛出两个异常
    • 主体账号不正确:抛出org.apache.shiro.authc.UnknownAccountException
    • 主体密码不正确:抛出org.apache.shiro.authc.IncorrectCredentialsException

模拟真实地从数据库查询对比验证登录之自定义Realm方式

public class MyRealm extends AuthorizingRealm {

    // 授权操作
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        return null;
    }

    // 认证操作
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println(authenticationToken);
        String username = (String)authenticationToken.getPrincipal();
        if(!"zhangsan".equals(username)){
            return null;
        }
        String password="666";
        // info对象表示realm登录对比信息,参数1:用户信息,参数2:表示密码,参数:3:当前ralms的名字
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, getName());
        return info;
    }

    // 指定当前自定义Realm的名字
    public String getName() {

        return "MyRealm";
    }
}


自定义ini配置文件
# 自定义realm
myRealm=com.wyq.shiro.realm.MyRealm
# 指定securityManager的realms实现
securityManager.realms=$myRealm

Shiro执行流程

  1. 构造SecuritiManager环境
  2. Subject.login(token)提交认证
  3. securitiManager.login()执行认证
  4. Authenticator执行认证
  5. Realm根据身份获取认证信息

Shiro加密

  • 散列算法:一般用于生成数据的摘要信息,是一种不可逆的算法,适合存储密码之类的数据,常见的散列算法有MD5、SHA等。
  • Shiro之MD5加密
    @Test
    public void testMD5() throws Exception{
        String password = "666";
        // 加密
        Md5Hash md5Hash = new Md5Hash(password);
        System.out.println(md5Hash);
        // 加密:md5 + salt
        md5Hash = new Md5Hash(password, "salt");
        System.out.println(md5Hash);
        // 加密:md5 + salt + 散列次数
        md5Hash = new Md5Hash(password, "salt", 3);
        System.out.println(md5Hash);
    }
  • Shiro之加密算法认证

    1. 自定义Realm类并继承AuthorizingRealm重写抽象方法
    public class PasswordRealm extends AuthorizingRealm {
        // 授权
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            return null;
        }
        // 认证
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            // 参数authenticationToken:表示登录时包装的UsernamePasswordToken
            // 通过用户名到数据库中查用户信息,封装成一个AuthonticationInfo对象返回,方便认证器进行对比
            // 获取token中的用户名
            String username = (String)authenticationToken.getPrincipal();
            if(!"zhangsan".equals(username)){
                return null;
            }
            // 模拟数据库中保存之后密文
            String password="c2fde5f6da6c08a5f4da78d5fd803bcd";
            // info对象表示realm登录对比信息,参数1:用户信息,参数2:表示密码,参数3:表示加密的salt, 参数:4:当前ralms的名字
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password , ByteSource.Util.bytes("salt"), getName());
            return info;
        }
    
        @Override
        public String getName() {
            return "PasswordRealm";
        }
    }
    
    1. 添加ini配置文件
    [main]
    # 定义凭证匹配器
    credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
    # 散列算法
    credentialsMatcher.hashAlgorithmName=md5
    # 散列次数
    credentialsMatcher.hashIterations=3
    
    # 自定义realm
    myRealm=com.wyq.shiro.realm.PasswordRealm
    myRealm.credentialsMatcher=$credentialsMatcher
    # 指定securityManager的realms实现
    securityManager.realms=$myRealm
    

Shiro权限管理

授权

  • RBAC:基于角色的权限管理
    • 用户对象:user-表示当前操作用户
    • 角色对象:role-表示权限操作许可权的集合
    • 权限对象:permission-资源操作许可权

权限管理的方式

  1. 编程方式
    • 通过写if/else授权代码完成
    Subject subject = SecurityUtils.getSubject();
    if(subject.hasRole("admin")){
        // 有权限
    }else{
        // 无权限
    }
    
  2. 注解方式
    • 通过在执行的java方法上放置相应的注解完成
    @RequiresRoles("admin")
    public void help(){
        
    }
    
  3. JSP标签方式
    • 在jsp页面通过相应的标签完成
    // 先引入标签库
    <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
    <shiro:hasRole name="admin">
        <!-- 有权限 -->
    </shiro:hasRole>
    

权限表达式

  • 在ini文件中用户、角色、权限的配置规则是:“用户名=密码,角色1,角色2…” “角色=权限1,权限2…”,首先根据用户名找角色,根据角色找权限,角色是权限的集合
  • 权限字符串的规则是:“资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,":"是资源/操作/实例的分割父,权限字符串也可以使用*统配符。
  • 例子
    • 用户创建权限:user:create,或user:create:*
    • 用户修改权限实例001的权限:user:update:001
    • 用户实例001的所有权限:user:*:001
  • 一般而言,我们操作只需要关注前面两节
    • 资源: 操作

权限管理之HelloWorld

    @Test
    public void testHasRole()throws Exception{
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");
        SecurityManager securityManager =  factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "666");
        subject.login(token);
        // 进行授权操作前提:用户必须通过认证
        System.out.println("是否拥有role1权限:" + subject.hasRole("role1"));
        System.out.println(subject.hasAllRoles(Arrays.asList("role1", "role2", "role3")));
        System.out.println(Arrays.toString(subject.hasRoles(Arrays.asList("role1", "role2", "role3"))));
        // 如果拥有角色不做任何操作,没有则抛出org.apache.shiro.authz.UnauthorizedException异常
        subject.checkRole("role1");
        // 判断是否拥有创建权限
        System.out.println(subject.isPermitted("user:create"));
    }
[users]
# 模拟数据库用户列表,账号=密码
zhangsan=666,role1,role2
lisi=888,role2

[roles]
# 角色role1对资源user拥有create,update的权限
role1=user:create,user:update
# 角色role2对资源user拥有create,delete的权限
role2=user:create,user:delete
# 角色role3对资源user拥有create的权限
role3=user:create

自定义Realm

  1. 添加配置文件
# 自定义realm
myRealm=com.wyq.shiro.realm.PermissionRealm
# 指定securityManager的realms实现
securityManager.realms=$myRealm
  1. 创建自定义认证类
public class PermissionRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // principalCollection 用户的凭证信息
        String username = (String)principalCollection.getPrimaryPrincipal();
        // 模拟查询数据库: 查询用户实现指定的角色,以及用户授权
        List<String> roles = new ArrayList<>();
        List<String> permission = new ArrayList<>();
        roles.add("role1");
        permission.add("user:*");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roles);
        info.addStringPermissions(permission);
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String)authenticationToken.getPrincipal();
        if(!"zhangsan".equals(username)){
            return null;
        }
        String password="666";
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
        return simpleAuthenticationInfo;
    }
    public String getName() {
        return "PermissionRealm";
    }
}
  1. 测试
    @Test
    public void testHasRoleByRealm()throws Exception{
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission-realm.ini");
        SecurityManager securityManager =  factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "666");
        subject.login(token);
        // 判断是否拥有某个权限
        System.out.println(subject.isPermitted("user:xx"));
    }

Shiro之web集成

  • Shiro与web集成,主要是通过配置一个shiroFilter过滤器拦截所有的url,其中ShiroFilter类似于SpringMVC的DispatcherServlet,是所有请求点的入口,负责根据配置(ini文件)判断请求进入rul是否需要登录/权限等工作。
  • 集成步骤
    1. 添加jar包
    <dependency>
    	<!-- shiro核心jar包  -->
    	<groupId>org.apache.shiro</groupId>
    	<artifactId>shiro-core</artifactId>
    	<version>1.2.3</version>
    </dependency>
    <!-- shiro与web集成的jar包  -->
    <dependency>
    	<groupId>org.apache.shiro</groupId>
    	<artifactId>shiro-web</artifactId>
    	<version>1.2.3</version>
    </dependency>
    
    1. 配置web.xml
    <context-param>
    	<param-name>shiroEnvironmentClass</param-name>
    	<param-value>org.apache.shiro.web.env.IniWebEnvironment</param-value>
    </context-param>
    <context-param>
    	<param-name>shiroConfigLocations</param-name>
    	<param-value>classpath:shiro.ini</param-value>
    </context-param>
    <listener>
    	<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
    </listener>
    <filter>
    	<filter-name>shiroFilter</filter-name>
    	<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
    </filter>
    <filter-mapping>
    	<filter-name>shiroFilter</filter-name>
    	<url-pattern>/*</url-pattern>
    </filter-mapping>
    
    1. 添加shiro.ini文件
    [main]
    #默认是/login.jsp
    authc.loginUrl=/login
    #用户无需要的角色时跳转的页面
    roles.unauthorizedUrl=/nopermission.jsp
    #用户无需要的权限时跳转的页面
    perms.unauthorizedUrl=/nopermission.jsp
    #登出之后重定向的页面
    logout.redirectUrl=/login
    
    [users]
    admin=666,admin
    zhangsan=666,deptMgr
    
    [roles]
    admin=employee:*,department:*
    deptMgr=department:view
    
    [urls]
    #静态资源可以匿名访问
    /static/**=anon
    #访问员工列表需要身份认证及需要拥有admin角色
    /employee=authc,roles[admin]
    #访问部门列表需要身份认证及需要拥有department:view的权限
    /department=authc,perms["department:view"]
    #当请求loginOut,会被logout捕获并清除session
    /loginOut=logout
    #所有的请求都需要身份认证
    /**=authc
    
    处理登录认证
    @WebServlet(name = "loginServlet", urlPatterns = "/login")
    public class LoginServlet  extends HttpServlet {
    	@Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		doPost(req, resp);
        }
    	@Override
    	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
    			throws ServletException, IOException {
    		String exceptionClassName = (String)req.getAttribute("shiroLoginFailure");
    		// 不处理登录成功的情况,shiro认证会自动跳转到上一个请求路径
    		// 处理登录失败的情况
    		if(exceptionClassName != null) {
    			if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
    				req.setAttribute("errorMsg", "账号不存在");
    			}else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
    				req.setAttribute("errorMsg", "用户名或密码错误");
    			}else {
    				req.setAttribute("errorMsg", "未知的登录异常");
    			}
    		}
    		// 登录失败还是跳回login页面
    		req.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(req, resp);
    		
    	}
    	
    }
    

Shiro与Spring整合

  • spring依赖
<!--shiro-->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.3</version>
    </dependency>
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.2.1</version>
    </dependency>

    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.2.2</version>
    </dependency>

    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>1.2.2</version>
    </dependency>
    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache-core</artifactId>
      <version>2.6.8</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>1.2.2</version>
    </dependency>

    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-quartz</artifactId>
      <version>1.2.2</version>
    </dependency>
    <!-- shiro与spring整合jar包 -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.2.2</version>
    </dependency>

web.xml配置

<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 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>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>SpringMVC</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>SpringMVC</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!--编码过滤器-->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>


  <!-- shiro过虑器,DelegatingFilterProx会从spring容器中找shiroFilter -->
  <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>

  1. 添加shiro-spring配置文件(注意引入该文件,不然报找不到shiroFilter错误)
<?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:aop="http://www.springframework.org/schema/aop"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
						   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <!--加密器-->
	<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
		<!--加密算法-->
		<property name="hashAlgorithmName" value="md5" />
		<!--散列次数-->
		<property name="hashIterations" value="3" />
	</bean>
    
	<!-- 登录验证 -->
	<!-- 1. 配置自定义的realm -->
	<bean id="userRealm" class="cn.wolfcode.shiro.realm.UserRealm">
		<!-- 密码需要加密: 加密器 -->
		<property name="credentialsMatcher" ref="credentialsMatcher"/>
		
		<property name="userDAO" ref="userDAOImpl"/>
		<property name="roleDAO" ref="roleDAOImpl"/>
		<property name="permissionDAO" ref="permissionDAOImpl"/>
	</bean>
    
    <!-- Shiro之缓存管理 -->
	<bean id="ehCacheManager" class ="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation" value="classpath:shiro-ehcache.xml" />
		<property name="shared" value="true"></property>
	</bean>
	<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
		<property name="cacheManager" ref="ehCacheManager"/>
	</bean>
	<!-- 2. 配置安全管理器SecurityManager -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="userRealm"/>
		<property name="cacheManager" ref="cacheManager"/> <!-- 给userRealm添加缓存机制 -->
	</bean>

	<!-- 3. 定义ShiroFilter, id必须跟web.xml中配置代理filter的filtername的值一致 -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager"/>
		<property name="loginUrl" value="/login"/><!-- 登录失败跳转的虚拟路径 -->
		<property name="unauthorizedUrl" value="/nopermission.jsp"/> <!-- 没有权限时跳转的路劲 -->
		<property name="filterChainDefinitions"> <!-- 所有的请求都必须经过这个过滤器 -->
			<value>
				/logout=logout
				/**=authc
			</value>
		</property>
	</bean>

	<!-- 权限控制 -->
	<!-- 开启spring的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>

	<!-- shiro权限异常处理,springMVC默认会处理异常,shiro即使配置了也不会起作用,必须开启shiro异常处理机制 -->
	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<prop key="org.apache.shiro.authz.UnauthorizedException">redirect:/nopermission.jsp</prop>
			</props>
		</property>
	</bean>
  1. 配置自定义Realm
public class UserRealm extends AuthorizingRealm {

    @Setter
    private IUserDAO userDAO;
    @Setter
    private IRoleDAO roleDAO;
    @Setter
    private IPermissionDAO permissionDAO;

    //认证操作
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //从token中获取登录的用户名, 查询数据库返回用户信息
        String username = (String) token.getPrincipal();
        User user = userDAO.getUserByUsername(username);
        SimpleAuthenticationInfo info = null;
        if(username != null){
            info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getUsername()), getName());
        }
        return info;
    }

    //授权操作
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User) principals.getPrimaryPrincipal();

        // 根据用户id查询所有角色
        List<String> roles = roleDAO.getRoleSnByUserId(user.getId());
        // 根据用户id查询该用户拥有的权限
        List<String> permissions = permissionDAO.getPermissionResourceByUserId(user.getId());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissions);
        info.addRoles(roles);
        return info;
    }

    @Override
    public String getName() {
        return "UserRealm";
    }

    //清除缓存
    public void clearCached() {
        //获取当前等的用户凭证,然后清除
        PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
        super.clearCache(principals);
    }
}
  • 权限控制
    • 在需要权限控制的方法上贴上权限标签:(此处仅仅讨论基于权限表达式为空:permission)

Shiro常用的一些JSP标签

<!-- 引入shiro标签库 -->
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

<!-- 显示登录的用户名 -->
<shiro:principal property="username"></shiro:principal>

<!-- 验证是否拥有某一个角色 -->
<shiro:hasRole name="管理员">
    用户拥有角色
</shiro:hasRole>

<!-- 如果该登录用户有对应的权限则显示标签内容,否则不显示 -->
<shiro:hasPermission name="department:list">
    用户拥有该权限
</shiro:hasPermission>

猜你喜欢

转载自blog.csdn.net/wangyanqun2017/article/details/85466492