`

Spring 3之MVC & Security简单整合开发(三)

阅读更多

为了方便学习,原文转自http://sarin.iteye.com/blog/832963

Security对数据库验证用户有两种方式,上文提到的是它默认支持的数据库表结构,但基本上用于实际是不现实的,因为我们的数据库都有自己的业务逻 辑,所以现在来看看怎么在我们自己的数据库上进行Security框架的用户验证整合,这里给出一个比较通用的数据库权限设计结构:

    假设我们的数据表名称为b_user和b_userrole,它们的结构如下:

CREATE TABLE `b_user` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `USERNAME` varchar(20) NOT NULL,
  `PASSWORD` varchar(32) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
CREATE TABLE `b_userrole` (
  `ID` int(11) NOT NULL,
  `USERID` int(11) NOT NULL,
  `ROLE` varchar(15) NOT NULL,
  PRIMARY KEY (`ID`),
  KEY `FK_USERID_USERROLE` (`USERID`),
  CONSTRAINT `FK_USERID_USERROLE` FOREIGN KEY (`USERID`) REFERENCES `b_user` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8


    那么表名,字段名和结构都和Security框架默认的不匹配,只好通过SQL语句来让Security框架识别了,在配置文件的数据库验证部分,我们可以这么来写:

	<security:authentication-manager>
		<security:authentication-provider>
			<security:password-encoder ref="md5Encoder" />
			<security:jdbc-user-service
				data-source-ref="dataSource"
				users-by-username-query="select USERNAME,PASSWORD,'true' as ENABLED from b_user where USERNAME=?"
				authorities-by-username-query="select u.USERNAME,ur.ROLE as AUTHORITIES from b_user u,b_userrole ur where u.USERNAME=? and u.ID=ur.USERID" />
		</security:authentication-provider>
	</security:authentication-manager>


    在jdbc-user-service中,我们启用了两个属性,其中放置的是SQL语句,就是我们自定义的用户验证方式,将我们的数据库设计和Security框架相匹配,这里的角色一定是在拦截url标签中配置过的,否则Security框架不能识别用户身份。
    启动应用程序,发现这和原来的验证效果是一样的,这就是自定义的数据库验证方式了。也非常简单,就是用SQL语句查询结果匹配Security框架,不过这可能要和自己应用的数据库设计做出调整,尽量做到最小调整。
    这里补充一点用户验证方式的配置,我们已经使用了在配置文件里配置用户和数据库验证,一种是支持为数不多的用户,一种是支持数据库大量查询的。对于前者, 将配置信息写在XML文件中,和Security框架的配置信息粘在一起,不利于维护。其实Security框架也支持属性文件的配置,我们可以这么来 写:

<security:authentication-manager>
	<security:authentication-provider>
		<security:user-service properties="/WEB-INF/users.properties"/>
	</security:authentication-provider>
</security:authentication-manager>


    这里把用户信息都写在了users.properties里,我们来看这个属性配置文件:

admin=123,ROLE_ADMIN,ROLE_USER
user1=123,ROLE_USER
user2=123,enabled,ROLE_USER


    这里面名/值对的形式排列的,值的字段比较多,我们来逐个解释。admin/user1是用户名,不用多说,等号后面第一位是密码,这里没有加密。第二位 是状态,这是可选的,默认是enabled,第三位以后就是用户所拥有的角色了,这么使用和前面的效果也是相同的。
    用户验证部分基本就这么多内容,这里没有涉及到LDAP相关部分。下面是访问控制的说明,访问控制是Security框架的另一大特性,可以对其进行自定义的扩展,设计符合我们业务逻辑的控制。这比URL拦截又深入了一步,可以过滤的东西又多了。
    设计到访问控制,要引入一个概念,谁来决定能否访问,从而进行控制。Security框架中的访问控制管理有三种方案:至少有一个同意访问,全部同意访 问,全部弃权或都同意访问(也就是没有拒绝的)。如何同意?投票产生!Security框架一个可配置的元素就出来了,那就是投票器了。和现实的投票一 样,分同意,反对和弃权三类。
    下面我们应用第一类访问控制管理:至少有一个投票器同意访问,在配置文件中这么来设置:

<bean id="accessDecisionManager"
	class="org.springframework.security.access.vote.AffirmativeBased">
	<property name="decisionVoters">
		<list>
			<bean class="org.springframework.security.access.vote.RoleVoter" />
			<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
		</list>
	</property>
</bean>


    上面是默认需要的认证投票,下面就是我们定制的内容了,用来满足特定需要。在消息发布应用中,有这样一个需求,在服务器上登录的用户,给可以删除消息的权 限,也就是说不用管理员账户登录,也能删除。那么我们就需要对访问进行控制。在服务器本身登录的用户的IP应该是本地地址127.0.0.1,那么只要 IP是它的允许删除,我们来自定义一个投票器来进行投票:

package org.ourpioneer.board.security;
import java.util.Collection;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
public class IPAddressVoter implements AccessDecisionVoter {
	public static final String IP_PREFIX = "IP_";
	public static final String IP_LOCAL_HOST = "IP_LOCAL_HOST";
	public boolean supports(ConfigAttribute attribute) {
		return attribute.getAttribute() != null
				&& attribute.getAttribute().startsWith(IP_PREFIX);
	}
	public boolean supports(Class<?> clazz) {
		return true;
	}
	public int vote(Authentication authentication, Object object,
			Collection<ConfigAttribute> attributes) {
		if (!(authentication.getDetails() instanceof WebAuthenticationDetails)) {
			return ACCESS_DENIED;
		}
		WebAuthenticationDetails details = (WebAuthenticationDetails) authentication
				.getDetails();
		String address = details.getRemoteAddress();
		int result = ACCESS_ABSTAIN;
		for (ConfigAttribute config : attributes) {
			result = ACCESS_DENIED;
			if (IP_LOCAL_HOST.equals(config.getAttribute())) {
				if (address.equals("127.0.0.1")
						|| address.equals("0:0:0:0:0:0:0:1")) {
					return ACCESS_GRANTED;
				}
			}
		}
		return result;
	}
}


    IP地址投票器仅处理属性开头是IP的访问,而支持访问的只能是IP_LOCAL_HOST访问属性。如果访问者的IP是127.0.0.1或者0:0:0:0:0:0:0:1的可以访问,其余的拒绝访问。在配置文件的投票器list中再加入这个类:

<bean class="org.ourpioneer.board.security.IPAddressVoter" />


    之后还要在URL拦截属性中修改配置IP_LOCAL_HOST属性的访问权限:

<security:intercept-url pattern="/messageDelete.htm"	access="ROLE_ADMIN,IP_LOCAL_HOST" />


    而且在http中还要配置访问决定管理器,否则是不能识别到IP_LOCAL_HOST的:

<security:http access-decision-manager-ref="accessDecisionManager">


    此时,在本地用user1用户登录,也具有了删除权限,可以删除文章了。这就是投票器的简单应用了。下面是方法调用安全,这是非常细粒度的安全控制,可以 作用于类的方法,那么也就是说,对一块业务逻辑有权限的用户组,可能允许你能添加而不能删除,他能修改而不能添加和删除,这都是可以实现的,因为这已经细 化到了方法之上了,一个类的某一个方法给你授权访问,其余方法就访问不到,细化到一个功能点上的访问,安全性有很大的提升。先看看对控制器方法的安全访 问,这个配置相对简单,在配置文件中,把安全配置文件和controller的声明放在一起:

<context:component-scan base-package="org.ourpioneer.board.web" />
<security:global-method-security
		jsr250-annotations="enabled" secured-annotations="enabled" />


    这样才能对controller的方法进行控制。不过对方法实行安全控制之后,就没有必要对URL进行拦截了,http配置中的url拦截就都可以去掉了,仅留下登录和退出的就可以了:

<security:http access-decision-manager-ref="accessDecisionManager">
	<security:form-login login-page="/login.jsp"
		login-processing-url="/login" default-target-url="/messageList.htm"
			authentication-failure-url="/login.jsp?error=true" />
	<security:logout logout-success-url="/login.jsp" />
</security:http>


    虽然这里加入了access-decision-manager-ref="accessDecisionManager",但是对方法的安全不是这里做 的,所以这样的话使用user1登录就没有对消息的删除权限了,那么怎么能恢复呢?很简单,在global-method-security中加入它就可 以了。这就完成了对控制器方法的配置,那么因为前面都是注解实现的,所以在方法上配置注解就行了,前面代码很全,这里给出一个示例:

@RequestMapping(method = RequestMethod.GET)
@Secured( { "ROLE_ADMIN", "IP_LOCAL_HOST" })
public String messageDelete(
	@RequestParam(required = true, value = "messageId") Long messageId,
			Model model) {
	Message message = messageBoardService.findMessageById(messageId);
	messageBoardService.deleteMeesage(message);
	model.addAttribute("messages", messageBoardService.listMessages());
	return "redirect:messageList.htm";
}


    只要在注解方法上表明可访问的权限就能实现拦截了。当然在Service上实现拦截同理可得,只是需要注意一下注解声明的所在配置文件,否则可能无效,这 确实有点不爽。方法拦截除了注解,还有嵌入配置方式和切点配置方式,这两种都是常规做法,参考官方文档就可以了。
    最后一点是V层的拦截,这在前面已经提到了,使用的是Security框架的标签库实现的。可用的标签和属性,直接参考官方文档即可,使用也很方便,这里就不过多说明了。
    Spring 3的MVC和Security框架的简单整合就介绍完了,没有过深内容,都是基础应用,如果想深入了解,官方文档是最佳的学习资料。本文的示例代码请直接下载,需要Maven环境来支持,关于Maven环境的配置,可以参考Maven构建Java Web开发环境 的介绍。
    欢迎交流,希望对使用者有用。

分享到:
评论

相关推荐

    基本的spring mvc + spring security实现的登录(无数据库)

    这个简单的示例为初学者提供了一个了解Spring MVC和Spring Security交互的基础平台,有助于理解这两个框架在实际项目中的作用和集成方式。通过深入研究和实践,可以进一步提升Web应用的安全性和可维护性。

    spring+spring mvc+mybatis框架整合实现超市货物管理系统

    总的来说,"spring+spring mvc+mybatis框架整合实现超市货物管理系统"是一个涵盖后端开发基础技能的项目,涉及了JavaEE的多个层面,从Web层的路由处理,到业务逻辑的实现,再到数据库操作,以及用户认证和分页显示等...

    spring security、 mybatis、 spring mvc 整合权限管理系统

    在IT领域,构建一个权限管理系统是企业级应用的常见需求,Spring Security、MyBatis和Spring MVC的整合正是实现这一目标的有效方式。这三个组件分别在不同的层面上为系统提供了强大的支持。 Spring Security是一款...

    spring3mvc+hibernate4+spring-security3+dwr3整合架包

    本篇文章将深入探讨“spring3mvc+hibernate4+spring-security3+dwr3整合架包”中的核心技术和概念,帮助开发者理解如何利用这些组件来创建强大的Java Web应用。 首先,Spring MVC(Model-View-Controller)是Spring...

    SSM框架的配置搭建 spring、 spring mvc、 mybatis 整合详解

    SSM框架,即Spring、Spring MVC和MyBatis的整合,是Java开发中常见的Web应用框架,用于构建高效、灵活的后端服务。本教程将详细介绍如何配置和搭建这一框架,帮助开发者理解其核心概念和操作流程。 首先,我们要...

    Spring mvc spring security Thymeleaf and Bootstrap

    Spring MVC、Spring Security、Thymeleaf 和 Bootstrap 是构建现代Web应用程序的重要技术栈。下面将分别详细介绍这些技术及其在后台管理中的应用。 1. Spring MVC: Spring MVC是Spring框架的一个模块,专门用于...

    Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)所有实验及实验报告.zip

    9. 整合Spring Security实现权限控制,了解角色和权限的概念。 10. 编写单元测试和集成测试,确保代码质量。 实验报告部分则会深入分析每个实验的实现过程,遇到的问题及解决方案,以及对整个开发流程的反思和总结...

    spring mvc,spring, hibernate 整合登录实例

    在本文中,我们将深入探讨如何将Spring MVC、Spring和Hibernate这三大流行框架整合在一起,以构建一个完整的登录实例。这个实例旨在提供一个清晰、简洁且易于理解的代码结构,帮助初学者快速上手。 首先,Spring ...

    SpringMVC+springAOP+spring security+Hibernate整合实例代码

    Spring MVC、Spring AOP、Spring Security和Hibernate是Java开发中常用的四大框架,它们各自负责不同的领域,但在实际项目中往往需要进行整合以实现更高效、更安全的开发。本实例代码提供了一个完整的整合示例,涵盖...

    《Java EE企业级应用开发教程Spring+Spring MVC+MyBatis》_源代码.zip

    《Java EE企业级应用开发教程Spring+Spring MVC+MyBatis》是一本深入探讨Java企业级应用程序开发的书籍,源代码包含多个章节的实例,旨在帮助读者理解和掌握使用Spring、Spring MVC和MyBatis框架进行实际开发的关键...

    springMVC注解+ security + redis 实例

    在IT行业中,Spring MVC、Spring Security和Redis是三个非常重要的技术组件,它们分别在Web开发、权限管理和数据缓存方面发挥着关键作用。下面将详细解释这三个技术以及它们如何协同工作。 **Spring MVC** Spring ...

    spring mvc + spring + hibernate 全注解整合开发视频教程 10

    在本教程中,我们将深入探讨如何使用Spring MVC、Spring和Hibernate三大框架进行全注解的整合开发。这个视频教程系列的第十部分将聚焦于实际应用中的细节和优化,旨在帮助开发者构建高效、可维护的Java Web应用程序...

    spring hibernate security整合

    在Java Web开发中,Spring、Hibernate和Spring Security是三个非常重要的框架。Spring作为一个全面的开发框架,提供了依赖注入(DI)和面向切面编程(AOP)等功能;Hibernate则是一个强大的对象关系映射(ORM)工具...

    swagger和spring mvc整合

    Swagger 和 Spring MVC 的整合是现代 Web 应用开发中常用的一种技术组合,它使得开发者能够快速构建具有高质量API文档的应用程序。Swagger 是一个强大的开源工具,用于设计、构建、记录和使用 RESTful 风格的 Web ...

    spring3_MVC实战

    【Spring3_MVC实战】系列将引导初学者逐步掌握基于注解的Spring3 MVC框架,事务管理和与Hibernate的集成开发。以下将详细讲解这个过程的各个步骤。 首先,我们需要确认开发环境。对于Java开发,JDK是基础,此处推荐...

    spring Security整合SSH

    SSH是Java开发中常用的三大框架组合,它们各自负责不同的职责:Struts2处理MVC(模型-视图-控制器)架构,Spring提供依赖注入和事务管理,Hibernate则作为ORM(对象关系映射)工具,负责数据库操作。 首先,让我们...

    spring mvc + spring + hibernate 全注解整合开发视频教程 13

    在本教程中,我们将深入探讨如何使用Spring MVC、Spring和Hibernate三大框架进行全注解的整合开发。这个视频教程系列的第13部分,将帮助开发者掌握如何在Java Web项目中高效利用这些技术,实现一个现代化、高效且可...

    SpringMVC集成SpringSecurity

    SpringMVC 和 SpringSecurity 是两个在Java Web开发中极为重要的框架。SpringMVC 主要负责处理Web应用的请求-响应模型,提供了一种强大的、可扩展的架构来构建现代的、基于HTTP的服务。而SpringSecurity,则是用于...

    基于spring+spring mvc+hibernate的智能农业信息管理系统

    通过整合Spring、Spring MVC和Hibernate,系统能够实现高效的数据管理、灵活的业务流程和强大的安全防护,为智能农业信息管理提供有力的技术支撑。在实际应用中,开发者可以根据农业场景的具体需求,对系统进行定制...

    springMvc+mybatis+springSecurity整合demo

    Spring MVC、MyBatis 和 Spring Security 是 Java Web 开发中常用的三大框架,它们各自负责不同的职责,但在实际项目中常被整合使用以构建强大的企业级应用。本整合 demo 展示了如何将这三个框架协同工作,提供高效...

Global site tag (gtag.js) - Google Analytics