实现授权精确控制的方法
精确的授权指的是基于用户特定的请求进行授权的应用功能特性。不同于我们在第二章:Spring Security起步、第三章增强用户体验和第四章凭证安全存储中的粗粒度的授权,精确的授权一般指的是对页面中的部分进行选择性显示的功能,而不是限制访问一个完整的页面。现实世界中的应用将会花费可观的时间用在规划精确授权的细节上。
Spring
Security为我们提供了两种方式来实现选择性显示的功能:
l Spring Security的JSP标签库允许通过标准的JSP标签库语法在页面本身添加条件访问声明;
l 在MVC应用的控制层,检查用户的授权从而使得控制层做出能否访问的判断并将决定的结果绑定到模型数据提供给视图层。 这种方式依赖于标准的JSTL条件实现界面渲染和数据绑定,这种方式比Spring Security JSP标签库复杂一些,但是,它与标准的web应用MVC逻辑设计更吻合。
在开发精确控制授权的web应用时,这两种方法都能很好的实现功能。让我们通过JBCP Pets用例来介绍没种方法的实现。
我们希望使用安全规划的结果来保证在网站范围内的菜单栏上“退出”和“我的订单”链接只能对登录过的或已购买的用户(分别为ROLE_USER和ROLE_CUSTOMER)显示。我们还会保证“登录”链接只对浏览站点的未认证访客(不具备ROLE_USER的用户)可见。我们将会介绍这两种添加该功能的方式,首先从Spring Security的JSP标签库开始。
使用Spring Security的标签库有选择地渲染内容
我们在第三章中见到过,可以使用Spring
Security的标签库访问存在于Authentication对象中的数据,这里我们将会见识到标签库的一些其它强大功能。Spring Security标签库最常用的功能就是基于授权规则有条件地渲染页面的各部分。这是通过<authorize>标签来实现的,它与JSTL核心库的<if>标签类似,在标签体中的内容是否显示由标签属性的条件结果来确定。让我们使用<authorize>标签按条件显示页面的部分。
基于URL访问规则进行有条件渲染
Spring Security的标签库提供了按照已有的URL授权规则进行内容渲染的功能,而URL授权规则已经在应用安全的配置文件中进行了定义。这是通过使用<authorize>标签的<url>属性来达到的。
例如,我们要保证“My Account”链接只能对实际登录站点的用户显示——回忆一下我们在前面定义的如下访问规则:
<intercept-url pattern="/account/*.do"
access="hasRole('ROLE_USER') and fullyAuthenticated"/>
所以,JSP中条件显示“My
Account”链接的代码如下所示:
<sec:authorize url="/account/home.do">
<c:url value="/account/home.do" var="accountUrl"/>
<li><a href="${accountUrl}">My Account</a></li>
</sec:authorize>
这能够保证除非用户拥有足够的权限来访问指定的URL,否则tag中的内容不会显示。还可以通过HTTP方法实现更高质量的检查,这要通过method属性来设置。
<sec:authorize url="/account/home.do" method="GET">
<c:url value="/account/home.do" var="accountUrl"/>
<li><a href="${accountUrl}">My Account</a> (with 'url' attr)</li>
</sec:authorize>
使用url属性对代码块定义授权检查的方法是很方便的,因为它对JSP中的实际授权检查进行了抽象并将其保存在安全配置文件中。
【注意的是,HTTP方法应该与<intercept-url>安全声明中的一致,否则它们将不会按照你预期的进行匹配。另外,注意URL应该是对于web应用上下文根的相对路径(如同URL访问规则一样)。】
对于很多场景来说,使用<authorize>标签能够保证只有用户允许看见的前提下,正确地渲染链接或action相关的内容。需要记住的是,这个标签不仅能够包在一个链接外面,如果用户没有权限提交这个form的时候,它还能包在整个form外边。
基于Spring 表达式语言进行有条件渲染
另外,可以联合使用<authorize>标签和Spring表达式语言(SpEL)更灵活地显示JSP内容。
回忆一下在第二章中我们初次体验SpEL提供的强大表达式语言,Spring
Security对其进行了更强的扩展,从而能够对当前安全的请求构建表达式。如果我们对前面的例子使用SpEL进行重构的话,在<authorize>标签中限制访问“My Account”链接的代码应该如下:
<sec:authorize access="hasRole('ROLE_USER') and fullyAuthenticated">
<c:url value="/account/home.do" var="accountUrl"/>
<li><a href="${accountUrl}">My Account</a> (with 'access' attr)</li>
</sec:authorize>
对SpEL进行求值计算的代码与<intercept-url>所定义的访问规则(假设配置了表达式)背后所使用的代码是一样的。所以,同样的内置函数和属性在<authorize>标签中都是可以通过表达式使用的。
以上的两种使用<authorize>的方式都可以实现基于安全授权规则对页面显示内容进行精确控制渲染的强大功能。
使用Spring Security2的方式进行有条件渲染
以上提到的两种使用Spring
Security标签库的方法实际上是Spring Security3新增的功能,并且这也是按照授权规则实现页面级安全的推荐方法;但是,同样是<authorize>标签支持其他的操作方法,这可能会在遗留代码中遇到,也可能在一定场景下,这样的方式能够更好的满足你的需求。
基于缺失某角色有条件显示内容
“Log In”链接应该只能对匿名的用户显示,也就是没有ROLE_USER角色的用户。<authorize>标签通过ifNotGranted属性支持这种类型的规则:
<sec:authorize ifNotGranted="ROLE_USER">
<c:url value="/login.do" var="loginUrl"/>
<li><a href="${loginUrl}">Log In</a></li>
</sec:authorize>
如果你现在以匿名用户试图访问站点,将会看到一个指向登录form的链接。
基于拥有列表中的某一个角色有条件显示内容
如同上一步那样,“Log
Out”链接应该对拥有账号且已经登录的用户进行显示。ifAnyGranted属性在渲染内容前,要求用户拥有几个特定角色中的任何一个。我们用“Log Out”链接的方式来展示其使用:
<sec:authorize ifAnyGranted="ROLE_USER">
<c:url value="/logout" var="logoutUrl"/>
<li><a href="${logoutUrl}">Log Out</a></li>
</sec:authorize>
注意的是ifAnyGranted属性允许是以逗号分隔的角色集合来确定适当的匹配结果,用户只需要拥有角色中的任意一个标签中的内容就会渲染。
基于拥有列表中的所有个角色有条件显示内容
最后,使用ifAllGranted属性要求用户拥有标签中定义的所有角色:
<sec:authorize ifAllGranted="ROLE_USER,ROLE_CUSTOMER">
<c:url value="/account/orders.do" var="ordersUrl"/>
<li><a href="${ordersUrl}">My Orders</a></li>
</sec:authorize>
我们能够看到authorize标签的多种语法,以在不同的环境下使用。注意的是我们在前面讲到的三个属性可以组合使用。如ifNotGranted和ifAnyGranted属性能够联合使用以提供稍微复杂的Boolean等式。
使用JSP表达式
以上的三种页面授权方法((ifNotGranted,ifAnyGranted,
ifAllGranted)支持JSP EL表达式,它将会执行并返回授权的GrantedAuthority(角色等)。如果授权要求的列表会根据页面计算结果而变化的话,这将会提供一定的灵活性。
分享到:
相关推荐
springboot springsecurity动态权限控制,实现数据库动态管理菜单权限
struts2 + spring3 + hibernate3 + spring security3 + mysql + tomcat sys_users;sys_roles;sys_authorities;sys_resources;sys_users_roles;sys_roles_authorities;sys_authorities_resources; PS:此项目运行不...
本项目基于Spring,整合Spring的security模块,实现用户管理和权限控制,是一套较为通用的权限控制功能,主要内容如下: 1.登录,包括“记住我”的功能; 2.加密,存储的密码不采用明文,初始密码1234; 3.拦截器...
SpringBoot+SpringSecurity整合示例代码,实现了从数据库中获取信息进行登录认证和权限认证。 本项目为idea工程,请用idea2019导入(老版应该也可以)。 本项目用户信息所需sql文件,在工程的resources文件夹下,...
基于springMVC+mybatis+mysql实现。基于SpringSecurity权限控制的简单工程DEMO。maven构建.
SpringSecurity 全套开发,设计源码解读,整个拦截器链分析,QQ登录,微信登录,短信验证,短信登录,在security基础上学习写一个自定义验证授权设计模式,整套视频讲解的分享细致认真,非常值得学习。不管小白还是...
通过修改spring security源代码实现动态权限管理。用户信息、角色信息和资源信息保存在数据库中,可动态配置权限,不用重新启动服务。改完即时生效,付例子
SpringSecurity+OAuth2+JWT分布式权限控制
springsecurity(用spring ibatis freemaker)实现的权限管理页面, 里头包括数据库脚本和原代码 主要参考http://blog.csdn.net/k10509806/article/details/6369131 这个人的文章做的
一个学习Spring Security权限控制的demo,使用的IDE是idea。
SpringBoot整合权限控制SpringSecurity
SpringBoot+SpringSecurity+JWT+MybatisPlus实现基于注解的权限验证,可根据注解的格式不同,做到角色权限控制,角色加资源权限控制等,粒度比较细化。 @PreAuthorize("hasAnyRole('ADMIN','USER')"):具有admin或...
非常详细的Spring Security 权限控制中文API
(1)该项目是基于spring3+struts2+hibernate3+spring security3的权限管理项目 (2)后台我已经实现了权限管理,包括用户,角色和资源的分配。前台实现了spring security3的管理 (3)网上案例普遍是后台单一登陆。...
Spring security认证授权例子,自动创建数据库,在SysUser类增加字段,即可动态增加数据库对应表sys_user字段(前提是要删除原表,启动应用时才会重建表)
后端使用SpringBoot框架进行业务逻辑开发,利用Spring Security实现权限控制。数据库采用MySQL进行数据存储,使用MyBatis进行数据访问。 权限控制模块设计包括用户、角色和权限三个主要模块。用户模块用于管理用户...
第二章:springsecurity起步 第三章:增强用户体验 第四章:凭证安全存储 第五章:精确的访问控制 第六章:高级配置和扩展 第七章:访问控制列表(ACL) 第八章:对OpenID开放 第九章:LDAP目录服务 第十章:使用...
spring boot +spring security +thymeleaf 实现简单权限+remember-me功能
集成 spring securit, spring security oauth 和 spring social,实现 用户名密码登录,手机验证码登录,社交账号登录,基于jwt的sso,集群session管理等功能。
spring security3 中文版本