使用控制器逻辑进行有条件渲染内容
现在,让我们将刚刚用<authorize>标签实现的例子改成用java代码的方式。为了简洁起见,我们只实现一个例子,但实现基于控制器检查的其它例子是很简单直接的。
添加有条件显示的Log In链接
为了替代Spring
Security的<authorize>标签,我们假设在模型数据中有一个Boolean变量来标示是否显示显示“Log in”链接,而这个变量可以在视图上得到。在传统的MVC模式下,视图不了解模型为何拥有这个值,它只需要使用即可。我们使用Java Standard Tag Library (JSTL)的if标签,连同JSP EL表达式来实现有条件显示页面的部分。
<c:if test="${showLoginLink}">
<c:url value="/login.do" var="loginUrl"/>
<li><a href="${loginUrl}">Log In</a></li>
</c:if>
现在看一下如下的代码以了解我们如何在控制器中将数据填充到模型中。
基于用户的凭证提供模型数据
我们控制器的对象模型是符合面向对象模式的,所有的Spring MVC控制器扩展自一个简单的基类com.packtpub.springsecurity.web.controller.BaseController。这使得我们能够将通用的代码放在BaseController中,从而应用中所有的控制器都能够访问。首先,我们加入一个方法以从当前的request中得到Authentication的实现类:
protected Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
接下类,我们添加一个方法 填充showLoginLink模型数据,此处使用Spring
MVC的注解方式。
@ModelAttribute("showLoginLink")
public boolean getShowLoginLink() {
for (GrantedAuthority authority : getAuthentication().
getAuthorities()) {
if(authority.getAuthority().equals("ROLE_USER")) {
return false;
}
}
return true;
}
这个方法添加了@ModelAttribute注解,任何实现BaseController的控制器触发时,Spring MVC将会自动执行此方法。针对authorize标签方式的其它显示/隐藏功能,我们能够很简单地使用模型数据指令重复这种设计模式。
配置页面内授权的最好方式是什么?
与以前版本的标签库相比,Spring
Security 3 <authorize>标签的主要优势在于移除了很多使用中的困扰之处。在很多场景下,使用标签的url属性隔离了授权规则变化对JSP代码的影响。可以在以下场景下使用url属性:
l标签限制显示的功能能够通过一个简单url明确的声明;
l标签的内容能够明确的与URL隔离。
但是在典型的应用中,使用标签url属性的可能性会很低。现实情况下应用会比这个复杂的多,需要更多的相关逻辑才能确定如何渲染页面的各部分。
尽管使用Spring Security标签库来声明渲染页面部分的方法很诱人,这种方式基于sping的语法以及一些其它的方式(包括if...Granted和access方法),但是有很多情况下使用它并不是一个好主意:
l Tag标签并不支持比角色成员更复杂的条件。例如,如果我们的应用的UserDetails实现包含了自定义的属性,如IP过滤、地理位置等,这些情况使用标准的<authorize>都不能支持。
但是,这些可以通过自定义的JSP标签或使用SpEL表达式来支持。即使如此,JSP也会直接绑定业务逻辑,而这并不是推荐做法。
l <authorize>标签必须在每一个使用的页面中引用。这可能会导致本来通用的规则产生潜在的不一致性,而这会在不同的物理界面文件中存在。好的面向对象系统设计建议条件规则只在一个地方存在,并在使用的地方对其进行引用。
可以通过封装并且重用JSP页面的部分来减少这类问题的发生(我们通过使用通用的JSP头文件已经对此进行了阐述),但是在一个复杂的应用中这个问题在所难免。
l 不能在编译阶段校验规则的正确性。编译期常量能够在典型的基于java对象系统中使用,JSP tag标签需要(典型情况下)硬编码角色名字,而简单的拼写错误很难被察觉。
公平来讲,这样的拼写错误能够很容易地在运行应用的功能测试中发现,但是使用标准的Java组件单元测试这样的问题更容易被发现。
我们可以看到,尽管基于JSP方式的内容有条件渲染很便利,但是也有一些明显的不足。
所有的这些问题都能够通过在控制器中使用代码推送数据到视图层来解决。另外,在代码中进行高级的授权决定能够享受到重用、编译器检查以及适当分离模型、视图、控制器所带来的好处。
分享到:
相关推荐
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+OAuth2+JWT分布式权限控制
SpringSecurity 全套开发,设计源码解读,整个拦截器链分析,QQ登录,微信登录,短信验证,短信登录,在security基础上学习写一个自定义验证授权设计模式,整套视频讲解的分享细致认真,非常值得学习。不管小白还是...
通过修改spring security源代码实现动态权限管理。用户信息、角色信息和资源信息保存在数据库中,可动态配置权限,不用重新启动服务。改完即时生效,付例子
springsecurity(用spring ibatis freemaker)实现的权限管理页面, 里头包括数据库脚本和原代码 主要参考http://blog.csdn.net/k10509806/article/details/6369131 这个人的文章做的
一个学习Spring Security权限控制的demo,使用的IDE是idea。
SpringBoot整合权限控制SpringSecurity
(1)该项目是基于spring3+struts2+hibernate3+spring security3的权限管理项目 (2)后台我已经实现了权限管理,包括用户,角色和资源的分配。前台实现了spring security3的管理 (3)网上案例普遍是后台单一登陆。...
SpringBoot+SpringSecurity+JWT+MybatisPlus实现基于注解的权限验证,可根据注解的格式不同,做到角色权限控制,角色加资源权限控制等,粒度比较细化。 @PreAuthorize("hasAnyRole('ADMIN','USER')"):具有admin或...
非常详细的Spring Security 权限控制中文API
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 中文版本