`
jinnianshilongnian
  • 浏览: 21514095 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2420554
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:3010289
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5640621
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:260243
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1597966
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:250375
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5860628
Group-logo
跟我学Nginx+Lua开...
浏览量:702897
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:785763
社区版块
存档分类
最新评论

第九章 JSP标签——《跟我学Shiro》

阅读更多

 

目录贴: 跟我学Shiro目录贴

 

Shiro提供了JSTL标签用于在JSP/GSP页面进行权限控制,如根据登录用户显示相应的页面按钮。

 

 

导入标签库

<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

标签库定义在shiro-web.jar包下的META-INF/shiro.tld中定义。

 

guest标签 

<shiro:guest>
欢迎游客访问,<a href="${pageContext.request.contextPath}/login.jsp">登录</a>
</shiro:guest> 

 

用户没有身份验证时显示相应信息,即游客访问信息。

 

user标签 

<shiro:user>
欢迎[<shiro:principal/>]登录,<a href="${pageContext.request.contextPath}/logout">退出</a>
</shiro:user> 

用户已经身份验证/记住我登录后显示相应的信息。

  

authenticated标签 

<shiro:authenticated>
    用户[<shiro:principal/>]已身份验证通过
</shiro:authenticated> 

用户已经身份验证通过,即Subject.login登录成功,不是记住我登录的。    

 

notAuthenticated标签

<shiro:notAuthenticated>
    未身份验证(包括记住我)
</shiro:notAuthenticated> 

用户已经身份验证通过,即没有调用Subject.login进行登录,包括记住我自动登录的也属于未进行身份验证。 

 

principal标签 

<shiro: principal/>

显示用户身份信息,默认调用Subject.getPrincipal()获取,即Primary Principal。

 

<shiro:principal type="java.lang.String"/>

相当于Subject.getPrincipals().oneByType(String.class)。 

 

<shiro:principal type="java.lang.String"/>

相当于Subject.getPrincipals().oneByType(String.class)。

 

<shiro:principal property="username"/>

相当于((User)Subject.getPrincipals()).getUsername()。   

 

hasRole标签 

<shiro:hasRole name="admin">
    用户[<shiro:principal/>]拥有角色admin<br/>
</shiro:hasRole> 

如果当前Subject有角色将显示body体内容。

 

hasAnyRoles标签 

<shiro:hasAnyRoles name="admin,user">
    用户[<shiro:principal/>]拥有角色admin或user<br/>
</shiro:hasAnyRoles> 

如果当前Subject有任意一个角色(或的关系)将显示body体内容。 

 

lacksRole标签 

<shiro:lacksRole name="abc">
    用户[<shiro:principal/>]没有角色abc<br/>
</shiro:lacksRole> 

如果当前Subject没有角色将显示body体内容。 

  

hasPermission标签

<shiro:hasPermission name="user:create">
    用户[<shiro:principal/>]拥有权限user:create<br/>
</shiro:hasPermission> 

如果当前Subject有权限将显示body体内容。 

  

lacksPermission标签

<shiro:lacksPermission name="org:create">
    用户[<shiro:principal/>]没有权限org:create<br/>
</shiro:lacksPermission> 

如果当前Subject没有权限将显示body体内容。

 

另外又提供了几个权限控制相关的标签:

 

导入自定义标签库 

<%@taglib prefix="zhang" tagdir="/WEB-INF/tags" %>

 

示例

<zhang:hasAllRoles name="admin,user">
    用户[<shiro:principal/>]拥有角色admin和user<br/>
</zhang:hasAllRoles>
<zhang:hasAllPermissions name="user:create,user:update">
    用户[<shiro:principal/>]拥有权限user:create和user:update<br/>
</zhang:hasAllPermissions>
<zhang:hasAnyPermissions name="user:create,abc:update">
    用户[<shiro:principal/>]拥有权限user:create或abc:update<br/>
</zhang:hasAnyPermissions> 

hasAllRoles表示拥有所有相关的角色;hasAllPermissions表示拥有所有相关的权限;hasAnyPermissions表示拥有任意一个相关的权限。

 

另外可以参考我的《简单shiro扩展实现NOT、AND、OR权限验证》实现NOT、AND、OR权限验证:http://jinnianshilongnian.iteye.com/blog/1864800

  

示例源代码:https://github.com/zhangkaitao/shiro-example;可加群 231889722 探讨Spring/Shiro技术。

 

16
6
分享到:
评论
12 楼 java_xh 2017-11-23  
感谢楼主,在处理system:user:* 语义的时候遇到点儿困难,之前我自己理解的是拥有system:user:下面任意一个权限就返回true,但是其实是满足所有权限才返回true,实际应用场景我更需要任意一个满足就返回true,所以我自己做了重新实现。

参照了源码,发现校验权限的方法实现主要是这两个
AuthorizingRealm.java 304行
protected boolean isPermitted(Permission permission, AuthorizationInfo info) {
	Collection perms = this.getPermissions(info);
	if(perms != null && !perms.isEmpty()) {
		Iterator var4 = perms.iterator();

		while(var4.hasNext()) {
			Permission perm = (Permission)var4.next();
			if(perm.implies(permission)) {
				return true;
			}
		}
	}

	return false;
}

WildcardPermission.java 85行
public boolean implies(Permission p) {
	if(!(p instanceof WildcardPermission)) {
		return false;
	} else {
		WildcardPermission wp = (WildcardPermission)p;
		List otherParts = wp.getParts();
		int i = 0;

		for(Iterator part = otherParts.iterator(); part.hasNext(); ++i) {
			Set otherPart = (Set)part.next();
			if(this.getParts().size() - 1 < i) {
				return true;
			}

			Set part1 = (Set)this.getParts().get(i);
			if(!part1.contains("*") && !part1.containsAll(otherPart)) {
				return false;
			}
		}

		while(i < this.getParts().size()) {
			Set var8 = (Set)this.getParts().get(i);
			if(!var8.contains("*")) {
				return false;
			}

			++i;
		}

		return true;
	}
}

这里我要修改*号的实现逻辑,必须要重写implies方法,所以我自定义了自己的CustomerPermission类,实现了WildcardPermission,代码如下
public CustomerPermission(String permissionString) {
	super(permissionString, false);
}

/**
 * 将当前需要验证的权限和用户拥有的权限之一对比,惹大于则返回true<br>
 * 重写的目的是为了将user:*的语义更改为any,即满足user:下面任何一个权限即可(原语义为满足user:下面所有权限)<br>
 *
 * @param p 表示当前需要验证的权限,  this 表示用户拥有的权限之一
 * @return boolean
 */
@Override
public boolean implies(Permission p) {
	if(!(p instanceof CustomerPermission)) {
		return false;
	} else {
		CustomerPermission wp = (CustomerPermission)p;
		List otherParts = wp.getParts();
		int i = 0;

		for(Iterator part = otherParts.iterator(); part.hasNext(); ++i) {
			Set otherPart = (Set)part.next();
			if(this.getParts().size() - 1 < i) {
				return true;
			}

			// 这里就是重写的重点,表示当前需要验证的权限当前是*号,那么就可以匹配任意权限,所以可以直接返回true
			if (otherPart.contains("*")) {
				return true;
			}

			Set part1 = (Set)this.getParts().get(i);
			if(!part1.contains("*") && !part1.containsAll(otherPart)) {
				return false;
			}
		}

		while(i < this.getParts().size()) {
			Set var8 = (Set)this.getParts().get(i);
			if(!var8.contains("*")) {
				return false;
			}

			++i;
		}

		return true;
	}
}


后面的事情就是要去把shiro的默认使用的WildcardPermission替换为CustomerPermission的实例,重写PermissionResolver
public class CustomerPermissionResolver implements PermissionResolver {
    @Override
    public Permission resolvePermission(String permissionString) {
        return new CustomerPermission(permissionString);
    }
}


替换shiro默认的WildcardPermission为CustomerPermission一开始是采用楼主文档中的ini配置,如下:
authorizer=org.apache.shiro.authz.ModularRealmAuthorizer
permissionResolver=com.fc.realm.CustomerPermissionResolver
authorizer.permissionResolver=$permissionResolver
securityManager.authorizer=$authorizer

后来发现这种方式无法替换permissionResolver,是因为在AuthenticatingRealm类的构造函数中有一句写死的赋值语句
public AuthorizingRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
	if(cacheManager != null) {
		this.setCacheManager(cacheManager);
	}

	if(matcher != null) {
		this.setCredentialsMatcher(matcher);
	}

	this.authorizationCachingEnabled = true;
	[color=red]this.permissionResolver = new WildcardPermissionResolver();[/color]
	int instanceNumber = INSTANCE_COUNT.getAndIncrement();
	this.authorizationCacheName = this.getClass().getName() + ".authorizationCache";
	if(instanceNumber > 0) {
		this.authorizationCacheName = this.authorizationCacheName + "." + instanceNumber;
	}

}


所以我在自定义的UserRealm类的构造函数中重新为该属性赋值了,即可达到效果,实现自己的权限校验逻辑
public UserRealm()
{
	super();
	// 这句话很重要,把自定义的PermissionResolver注入到AuthorizingRealm对象的permissionResolver中
	super.setPermissionResolver(new CustomerPermissionResolver());
}
11 楼 zj_璠璠 2017-03-03  
js中使用shiro好像无效
     
10 楼 德赫0625 2016-05-23  
notAuthenticated标签,这里的描述“用户已经身份验证通过”似乎写错了?应该是“用户身份未验证通过”吧
9 楼 xubao6000 2016-04-05  
为什么在页面之中引入<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>之后,加载速度从1-2秒变成 了大约1分钟左右呢?没有其它任何区别,只有引入标签的区别
8 楼 u011168185 2016-01-18  
我想请教一下,如果是html页面怎么办呢???
7 楼 u013609917 2016-01-15  
shiro 标签用js加好像无效   (菜鸟询问)
6 楼 sunwt 2014-05-08  
在sitemesh的decorator页面内使用shiro标签貌似不太好用啊~求解答
5 楼 freerambo 2014-05-07  
照着例子做了一天了,非常受用。 之处个小错误啊 在自定义标签中: hasAnyPermissions.tag 中,for循环中的判定条件 if(subject.isPermitted(permission)) ,一旦有一个命中就应该终止,我加的break; 否则的话会打印多次 jsp body


谢!!!taoge居然是非法字符。。。
4 楼 jinnianshilongnian 2014-03-06  
lyq881209 写道
jinnianshilongnian 写道
lyq881209 写道
问下,调用subject.logout(),缓存中的权限,session会清除吗,cache用的自定义缓存,和自定义的分布式session。

1、session会进行stop() stop时如果是自己做会话;可以实现自己的SessionDAO 进行删除;
2、cache会清除

session:用的是DefaultWebSessionManager,sessionDAO用的是继承AbstractSessionDAO的自定义类。
当subject.logout()或会话过期,需要自定义session监听器来手动清理吗。

实现SessionDAO 即可 你去看看它的api吧 里边有个doDelete方法
3 楼 lyq881209 2014-03-06  
jinnianshilongnian 写道
lyq881209 写道
问下,调用subject.logout(),缓存中的权限,session会清除吗,cache用的自定义缓存,和自定义的分布式session。

1、session会进行stop() stop时如果是自己做会话;可以实现自己的SessionDAO 进行删除;
2、cache会清除

session:用的是DefaultWebSessionManager,sessionDAO用的是继承AbstractSessionDAO的自定义类。
当subject.logout()或会话过期,需要自定义session监听器来手动清理吗。
2 楼 jinnianshilongnian 2014-03-06  
lyq881209 写道
问下,调用subject.logout(),缓存中的权限,session会清除吗,cache用的自定义缓存,和自定义的分布式session。

1、session会进行stop() stop时如果是自己做会话;可以实现自己的SessionDAO 进行删除;
2、cache会清除
1 楼 lyq881209 2014-03-06  
问下,调用subject.logout(),缓存中的权限,session会清除吗,cache用的自定义缓存,和自定义的分布式session。

相关推荐

    第十七章 OAuth2集成——《跟我学Shiro》 - 开涛的博客 - ITeye技术网站2

    在《跟我学Shiro》的第十七章中,作者开涛介绍了如何集成OAuth2,使用Apache Oltu作为OAuth2服务端的实现。实现中涉及以下关键部分: 1. **依赖**:引入了`authzserver`(授权服务器依赖)和`resourceserver`(资源...

    跟我一起学shiro 张开涛

    《跟我一起学Shiro——张开涛》这本书是针对初学者的优秀教程,旨在帮助读者快速理解和掌握Shiro的基本用法和核心概念。 **1. Shiro基础** Shiro的基础概念包括Subject、Realms、Cryptography和Session。Subject是...

    [资料][Java]跟我学Shiro教程_Java跟我学Shiro教程_shiro_

    Apache Shiro 是一个强大且易用的 Java 安全框架,提供了认证、授权、加密和会话管理功能,可以非常方便地开发出足够安全的应用。...阅读 "[资料][Java]跟我学Shiro教程.pdf",你将得到更详细的步骤指导和实践案例。

    《跟我学Shiro》- 张开涛.txt

    ***txt文件中含有下载地址** 《跟我学Shiro》- 张开涛,PDF版本,带目录,清晰。 示例源代码:https://github.com/zhangkaitao/shiro-example; 加qun 231889722 探讨Spring/Shiro技术。

    跟我学Shiro

    通过《跟我学Shiro》.pdf,你将学习到如何创建 Realm 实现数据源连接、配置 Shiro 安全框架、处理登录和登出逻辑、实现权限控制以及在实际项目中部署和调优 Shiro。 10. **最佳实践** 学习 Shiro 的过程中,了解...

    跟我学shiro

    #### 九、JSP 标签 - **概念**:Shiro 提供了一系列 JSP 标签,用于页面上的安全控制。 #### 十、会话管理 - **概念**:管理用户的会话信息,包括会话的创建、销毁、存储等。 - **组件**: - **会话**:存储用户...

    跟我学Shiro教程.rar

    "跟我学Shiro教程"这个资源显然是为了帮助学习者深入理解并掌握Shiro的核心概念和实际应用。 在Shiro的认证服务中,其主要目标是确认用户身份。这通常涉及用户登录过程,其中用户提供的凭证(如用户名和密码)被...

    跟我学Shiro教程及其课程分章节源码

    Apache Shiro是一个强大易用的Java安全框架,...我找了一版 跟我学Shiro教程PDF,里面讲的很详细.里面还附带了每个章节的源码.值得你收藏哟!饮水思源——原文出自:http://jinnianshilongnian.iteye.com/blog/2049092

    跟我学Shiro-java开发+spring开发

    《跟我学Shiro-java开发+spring开发》是一个深入学习Java安全框架Shiro和Spring集成的教程,旨在帮助开发者掌握这两个关键技术在实际项目中的应用。Shiro是一个强大的且易用的Java安全框架,提供了认证、授权、加密...

    跟我学Shiro教程 pdf

    《跟我学Shiro》PDF完结版下载, Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不...

    shiro教程 跟我学Shiro教程

    "跟我学Shiro教程"资源包包含了全面学习Shiro所需的重要材料,包括文档和实践示例。 首先,我们来看《Apache_Shiro参考手册中文版.pdf》。这本书籍详细介绍了Shiro框架的各个组件和使用方法。通过阅读,你可以了解...

    跟我学Shiro第11章Demo

    在"跟我学Shiro第11章Demo"中,我们将深入探讨Shiro的核心组件,特别是其在缓存管理和会话管理中的应用。 首先,我们关注的是Cache缓存。Shiro支持缓存来提高性能,避免频繁的数据库查询。它允许开发者将敏感操作的...

    跟我学 Shiro - v1.1.rar

    Apache Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Sp ring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所 ...

    跟我学shiro文档及源码

    在《跟我学Shiro》这本书中,作者深入浅出地讲解了 Shiro 的核心概念与实际应用场景,配合源码分析,有助于读者更好地理解和掌握 Shiro 的工作原理。 1. **Shiro 概述** - Shiro 的设计目标是简化应用安全开发,它...

    跟我学shiro源代码

    "跟我学Shiro源代码"是一份针对Shiro框架的详细教程,通过这本书,读者能够深入理解Shiro的核心概念和用法,并通过实际的代码示例来提升自己的技能。 1. **身份验证(Authentication)**:Shiro提供了一套完善的...

    跟我学shiro综合实例(springboot新版)

    **跟我学Shiro综合实例(SpringBoot新版)** 在当今的Web开发中,Spring Boot以其简洁的配置和快速的开发效率成为了许多项目首选的技术栈。而Apache Shiro作为一款强大的安全框架,它提供了身份验证、授权、会话...

Global site tag (gtag.js) - Google Analytics