- 浏览: 158849 次
- 性别:
- 来自: 奥克兰
文章分类
最新评论
-
u012625419:
...
CXF之用spring配置服务端和客户端实例(转) -
bambooshangye:
CXF之用spring配置服务端和客户端实例(转) -
最佳蜗牛:
写的很好,谢谢!
tomcat下的server.xml文件和context.xml (转) -
mohaowen1989:
亲 有中文版的么?在grails基础上的spring-secu ...
Simplified Spring Security with Grails(转) -
douhongyang:
挺好,,思路很清晰,
spring security详解教程 (转)
为了方便学习,原文出自http://sarin.iteye.com/blog/830831
现在来说Security部分。Spring Security框架是Acegi Security的升级,这个框架就是利用了多重过滤的机制对请求进行处理,将符合要求的请求放行,不符合要求的请求阻止下来,这是最大的原理。下面先来看看简单的url过滤吧。
先写一个用于验证身份的登录页面:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head> <title>Login</title> </head> <body> <c:if test="${not empty param.error}"> <font color="red">Login error.<br /> </font> Reason:${sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message} </c:if> <form method="POST" action="<c:url value="/login"/>"> <table> <tr> <td align="right">Username</td> <td><input type="text" name="j_username" /></td> </tr> <tr> <td align="right">Password</td> <td><input type="password" name="j_password" /></td> </tr> <tr> <td colspan="2" align="right"><input type="submit" value="Login" /> <input type="reset" value="Reset" /></td> </tr> </table> </form> </body> </html>
做一些说明,使用Spring
Security时,默认的登录验证地址是j_spring_security_check,验证的用户名是j_username,密码是
j_password,对于用户名和密码我们不需要修改,使用其默认值即可,而验证路径通常我们想使用自定义地址,这就需要在security中进行配
置,后面会看到,这里还会看到如果验证失败,会把失败信息打印出来,就是JSTL的c:if段的作用。下面来看最基本的Security框架作用,拦截
URL请求。在board-security.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> <security:http auto-config="true"> <security:intercept-url pattern="/messageList.htm" access="ROLE_ADMIN,ROLE_USER,ROLE_GUEST" /> <security:intercept-url pattern="/messagePost.htm" access="ROLE_ADMIN,ROLE_USER" /> <security:intercept-url pattern="/messageDelete.htm" access="ROLE_ADMIN" /> <security:anonymous username="guest" granted-authority="ROLE_GUEST" /> </security:http> <security:authentication-manager> <security:authentication-provider> <security:user-service> <security:user name="admin" authorities="ROLE_ADMIN,ROLE_USER" password="secret" /> <security:user name="user1" authorities="ROLE_USER" password="1111" /> </security:user-service> </security:authentication-provider> </security:authentication-manager> </beans>
配置文件中首先是对http请求的拦截,这里使用了自动配置auto-config,那么当请求到达时,Security框架会让我们进行身份验证,我们
拦截的url模式已经在其中配置出来,三个请求分别对应不同的权限,而且messageList.htm还开放了匿名访问功能,要提供匿名访问,就要配
置<anonymous>,这里我们配置匿名用户名为guest,角色是ROLE_GUEST,这里的角色都是ROLE_开头,是
Spring Security框架默认使用的,我们不用去更改,这也很清楚。首先我们启动应用,来访问唯一的匿名功能,之后我们看到如下效果:
可以看到,现在的角色是ROLE_GUEST,那么就直接看到,没有验证身份,若我们要发布消息呢,点击Post链接,看看效果:
要求身份验证了,这就说明对url的拦截起作用了,想发布消息,权限不够了,要验证身份了,注意这里这个页面并不是我们前面写的那个页面,而是
Security框架的默认验证页面,为什么没有使用我们所写的页面呢?因为我们还没有配置它啊,当然不会被识别到了。我们来看看默认的页面源码是什么样
子的:
<html><head><title>Login Page</title></head><body onload='document.f.j_username.focus();'> <h3>Login with Username and Password</h3><form name='f' action='/j_spring_security_check' method='POST'> <table> <tr><td>User:</td><td><input type='text' name='j_username' value=''></td></tr> <tr><td>Password:</td><td><input type='password' name='j_password'/></td></tr> <tr><td colspan='2'><input name="submit" type="submit"/></td></tr> <tr><td colspan='2'><input name="reset" type="reset"/></td></tr> </table> </form></body></html>
可以看到这里的默认请求路径就是/j_spring_security_check了,不过这里我们已经可以使用我们配置的用户来登录了,之前在配置文件
中的admin和user1,它们拥有的权限不同,那么我们使用user1登录,来发布消息。验证通过,出现消息输入页面:
下面发布消息,之后能看到消息的列表了,这对ROLE_USER的角色都是可以查看的。
没有把Author的信息打印出来,为什么?我们在这里对这个自动进行了限制,来看一下页面是怎么写的:
<security:authorize ifAllGranted="ROLE_ADMIN,ROLE_USER"> <tr> <td>Author</td> <td>${message.author}</td> </tr> </security:authorize>
这里说的是拥有ROLE_ADMIN和ROLE_USER两种角色才能显示author信息,显然我们权限不够了,当然把这里修改为
ifAnyGranted=”ROLE_ADMIN,ROLE_USER”就可以显示出来了,All和Any的区别嘛,很容易理解。还有一个属性是
ifNotGranted,不用说你也会明白它是什么意思了,我们现在修改为ifAnyGranted=”ROLE_ADMIN,ROLE_USER”,
刷新页面,就会看到如下内容了:
其实这已经是在扩展Security框架的视图功能了,就是这么使用的,如果想了解security框架标签库其它标签,那么去参考官方文档吧,因为你已经知道该怎么去套用了。
该试试删除功能了,当前用户角色是ROLE_USER,想删除肯定是不可以的了,那么会是怎么样的效果呢,点击Delete链接,看一下吧:
非常不幸,被拦截下来了,HTTP 403表示没有权限,那么就对了,Security框架起作用了,这就是我们想要的效果了。
Security框架的基本URL拦截到此就说完了,是不是很简单?下面就来定制一些操作吧,我们既然编写了自定义登录页面,得用上吧,还有Logout退出功能没用呢。下面就对这基本的配置进行第一次扩展,我们这样做:
<security:http> <security:intercept-url pattern="/messageList.htm" access="ROLE_ADMIN,ROLE_USER,ROLE_GUEST" /> <security:intercept-url pattern="/messagePost.htm" access="ROLE_ADMIN,ROLE_USER" /> <security:intercept-url pattern="/messageDelete.htm" access="ROLE_ADMIN" /> <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>
首先去掉auto-config,因为要定制,不让Security按它默认的执行。那么登录验证就配置吧,login-page属性配置的是登录页面,
就是我们前面所写的,login-processing-url就是我们处理登录逻辑的请求地址,默认的是
j_spring_security_check,前面也说过了,default_target_url就是默认的登录成功转向的目标地址,这里是消息列
表页面。最后一个属性是authentication-failure-url,很明白了,就是验证失败转向的页面,这里我们附加一个参数error,页
面里面也有体现,就是用它来控制失败信息的打印的。下面一个是配置退出,logout-success-url就是退出后转向的页面,这里是到登录页面,
没错,退出后回到登录页面。下面来看看效果吧,修改完毕重启Jetty:
由于去掉了匿名访问,那么直接请求messageList.htm就会为我们跳转到登录页面了,进行身份验证,此时我们输入一个错误的信息,看看能捕捉到什么:
验证失败错误会出现Bad credentials,这里不判断是用户不存在还是密码错误,统一是登录凭据错误。输入正确的信息就可以重复上述操作了。使用admin登录成功,会出现:
至此基本的Security拦截操作已经说完了,是不是很简单呢。当然这是测试的,真实应用中我们的用户不可能这么配置,因为都是存放在数据库中的,那么
Security能不能支持数据库用户验证呢?答案是肯定的。只是需要一些扩展配置,这里Security整合了一些数据库验证的操作,要符合
Security的验证模式,那么要么我们重新设计数据库,要么在原有基础之上来修改一下数据库设计。这里我们先看一下Security框架默认支持的数
据库设计吧,就是它默认SQL查询语句所支持的内容。
这两个表明是默认的,这么写Security会自己识别出来,不用我们书写SQL语句了。先来看看表设计吧,就这些信息就够Security进行验证了。
CREATE TABLE `users` ( `USERNAME` varchar(10) NOT NULL, `PASSWORD` varchar(32) NOT NULL, `ENABLED` tinyint(1) NOT NULL, PRIMARY KEY (`USERNAME`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CREATE TABLE `authorities` ( `USERNAME` varchar(10) NOT NULL, `AUTHORITY` varchar(10) NOT NULL, KEY `FK_USERNAME_AUTHORITY` (`USERNAME`), CONSTRAINT `FK_USERNAME_AUTHORITY` FOREIGN KEY (`USERNAME`) REFERENCES `users` (`USERNAME`) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB DEFAULT CHARSET=utf8
两个表之间有一个外键的关联,是用户名关联,而且我们还进行了md5密码扩展,这也要在Security框架进行配置,在表中插入一些信息,就可以进行数据库验证了,此时Security框架的配置如下,修改认证管理器:
<security:authentication-manager> <security:authentication-provider> <security:password-encoder ref="md5Encoder" /> <security:jdbc-user-service data-source-ref="dataSource" /> </security:authentication-provider> </security:authentication-manager>
这里我们配置了jdbc数据源和密码编码器,因为连MD5加密方式也是我们自定义的,这样安全系数更高。要使用自定义的加密器,别忘了编写加密器的bean。
<bean id="md5Encoder" class="org.ourpioneer.board.util.MD5Encoder" />
加密器类需要实现PasswordEncoder接口,然后编写我们自己的加密方案,加密器很简单,如下设计:
package org.ourpioneer.board.util; import org.springframework.dao.DataAccessException; import org.springframework.security.authentication.encoding.PasswordEncoder; public class MD5Encoder implements PasswordEncoder { public String encodePassword(String origPwd, Object salt) throws DataAccessException { return MD5.getMD5ofStr(origPwd); } public boolean isPasswordValid(String encPwd, String origPwd, Object salt) throws DataAccessException { return encPwd.equals(encodePassword(origPwd, salt)); } }
其中使用到的MD5加密类为:
package org.ourpioneer.board.util; import java.security.MessageDigest; /** * 标准MD5加密方法,使用java类库的security包的MessageDigest类处理 <BR> * 也可变为非标准MD5,请修改下面的移位算法 * * @author Nanlei * */ public class MD5 { /** * 获得MD5加密密码的方法 */ public static String getMD5ofStr(String origString) { String origMD5 = null; try { MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] result = md5.digest(origString.getBytes()); origMD5 = byteArray2HexStr(result); } catch (Exception e) { e.printStackTrace(); } return origMD5; } /** * 处理字节数组得到MD5密码的方法 */ private static String byteArray2HexStr(byte[] bs) { StringBuffer sb = new StringBuffer(); for (byte b : bs) { sb.append(byte2HexStr(b)); } return sb.toString(); } /** * 字节标准移位转十六进制方法 */ private static String byte2HexStr(byte b) { String hexStr = null; int n = b; if (n < 0) { // 若需要自定义加密,请修改这个移位算法即可 n = b & 0x7F + 128; } hexStr = Integer.toHexString(n / 16) + Integer.toHexString(n % 16); return hexStr.toUpperCase(); } /** * 提供一个MD5多次加密方法 */ public static String getMD5ofStr(String origString, int times) { String md5 = getMD5ofStr(origString); for (int i = 0; i < times - 1; i++) { md5 = getMD5ofStr(md5); } return getMD5ofStr(md5); } /** * 密码验证方法 */ public static boolean verifyPassword(String inputStr, String MD5Code) { return getMD5ofStr(inputStr).equals(MD5Code); } /** * 多次加密时的密码验证方法 */ public static boolean verifyPassword(String inputStr, String MD5Code, int times) { return getMD5ofStr(inputStr, times).equals(MD5Code); } /** * 提供一个测试的主函数 */ public static void main(String[] args) { System.out.println("123:" + getMD5ofStr("123")); System.out.println("123456789:" + getMD5ofStr("123456789")); System.out.println("pioneer:" + getMD5ofStr("pioneer")); System.out.println("123:" + getMD5ofStr("123", 4)); } }
加密工作已经准备好,之前配置的数据源是:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/board" /> <property name="username" value="root" /> <property name="password" value="123" /> </bean>
别忘了加入JDBC的驱动程序,之后我们就可以使用数据库用户验证了,剩下的步骤就和前面是一样的了。
至此我们已经了解了Security对标准设置的数据库验证的操作了,下一篇
将从非标准的数据库验证开始继续介绍Security框架。欢迎交流,希望对使用者有用。
发表评论
-
Spring MVC中修改校验的异常信息
2011-04-06 13:25 1689Spring MVC中修改校验的异常信息 原文转自: ... -
Spring 3之MVC & Security简单整合开发(三)
2011-03-01 11:01 1297为了方便学习,原文转自http://sarin.iteye.c ... -
Spring 3之MVC & Security简单整合开发(一)(转)
2011-03-01 10:58 1565为了方便学习,原文出自http://sarin.iteye.c ... -
Spring与Hibernate两种组合方式 (转)
2010-10-07 17:31 1881Spring与Hibernate大致有两种组合方式,主要区别是 ... -
Spring Security Acegi 学习之路四 (转)
2010-09-16 12:34 1685安全对象访问控制 Aceg ... -
Spring Security Acegi 学习之路三 (转)
2010-09-16 12:34 2370身份认证管理 使用 Acegi ... -
Spring Security Acegi 学习之路二(转)
2010-09-16 12:33 1456将 Acegi 集成到 ... -
Spring Security Acegi 学习之路一 (转)
2010-09-16 12:32 1391概述 Acegi Sec ... -
spring security详解教程 (转)
2010-09-16 12:29 2204先来谈一谈 Acegi 的基础知识, Acegi 的架 ... -
Spring的监听器 ContextLoaderListener的作用(转)
2010-07-07 11:18 1850在SSH项目中我们自动加载spring配置文件需要在web.x ...
相关推荐
这个简单的示例为初学者提供了一个了解Spring MVC和Spring Security交互的基础平台,有助于理解这两个框架在实际项目中的作用和集成方式。通过深入研究和实践,可以进一步提升Web应用的安全性和可维护性。
总的来说,"spring+spring mvc+mybatis框架整合实现超市货物管理系统"是一个涵盖后端开发基础技能的项目,涉及了JavaEE的多个层面,从Web层的路由处理,到业务逻辑的实现,再到数据库操作,以及用户认证和分页显示等...
本篇文章将深入探讨“spring3mvc+hibernate4+spring-security3+dwr3整合架包”中的核心技术和概念,帮助开发者理解如何利用这些组件来创建强大的Java Web应用。 首先,Spring MVC(Model-View-Controller)是Spring...
SSM框架,即Spring、Spring MVC和MyBatis的整合,是Java开发中常见的Web应用框架,用于构建高效、灵活的后端服务。本教程将详细介绍如何配置和搭建这一框架,帮助开发者理解其核心概念和操作流程。 首先,我们要...
在IT领域,构建一个权限管理系统是企业级应用的常见需求,Spring Security、MyBatis和Spring MVC的整合正是实现这一目标的有效方式。这三个组件分别在不同的层面上为系统提供了强大的支持。 Spring Security是一款...
Spring MVC、Spring Security、Thymeleaf 和 Bootstrap 是构建现代Web应用程序的重要技术栈。下面将分别详细介绍这些技术及其在后台管理中的应用。 1. Spring MVC: Spring MVC是Spring框架的一个模块,专门用于...
9. 整合Spring Security实现权限控制,了解角色和权限的概念。 10. 编写单元测试和集成测试,确保代码质量。 实验报告部分则会深入分析每个实验的实现过程,遇到的问题及解决方案,以及对整个开发流程的反思和总结...
《Java EE企业级应用开发教程Spring+Spring MVC+MyBatis》是一本深入探讨Java企业级应用程序开发的书籍,源代码包含多个章节的实例,旨在帮助读者理解和掌握使用Spring、Spring MVC和MyBatis框架进行实际开发的关键...
在本文中,我们将深入探讨如何将Spring MVC、Spring和Hibernate这三大流行框架整合在一起,以构建一个完整的登录实例。这个实例旨在提供一个清晰、简洁且易于理解的代码结构,帮助初学者快速上手。 首先,Spring ...
Spring MVC、Spring AOP、Spring Security和Hibernate是Java开发中常用的四大框架,它们各自负责不同的领域,但在实际项目中往往需要进行整合以实现更高效、更安全的开发。本实例代码提供了一个完整的整合示例,涵盖...
在IT行业中,Spring MVC、Spring Security和Redis是三个非常重要的技术组件,它们分别在Web开发、权限管理和数据缓存方面发挥着关键作用。下面将详细解释这三个技术以及它们如何协同工作。 **Spring MVC** Spring ...
在本教程中,我们将深入探讨如何使用Spring MVC、Spring和Hibernate三大框架进行全注解的整合开发。这个视频教程系列的第十部分将聚焦于实际应用中的细节和优化,旨在帮助开发者构建高效、可维护的Java Web应用程序...
Swagger 和 Spring MVC 的整合是现代 Web 应用开发中常用的一种技术组合,它使得开发者能够快速构建具有高质量API文档的应用程序。Swagger 是一个强大的开源工具,用于设计、构建、记录和使用 RESTful 风格的 Web ...
在实际开发中,我们可能会遇到一些常见的问题,例如事务的隔离级别设置、懒加载引起的“LazyInitializationException”、以及Spring Security与Spring MVC的拦截器顺序等。这些问题都需要根据具体需求进行调整和优化...
【Spring3_MVC实战】系列将引导初学者逐步掌握基于注解的Spring3 MVC框架,事务管理和与Hibernate的集成开发。以下将详细讲解这个过程的各个步骤。 首先,我们需要确认开发环境。对于Java开发,JDK是基础,此处推荐...
SSH是Java开发中常用的三大框架组合,它们各自负责不同的职责:Struts2处理MVC(模型-视图-控制器)架构,Spring提供依赖注入和事务管理,Hibernate则作为ORM(对象关系映射)工具,负责数据库操作。 首先,让我们...
SpringMVC 和 SpringSecurity 是两个在Java Web开发中极为重要的框架。SpringMVC 主要负责处理Web应用的请求-响应模型,提供了一种强大的、可扩展的架构来构建现代的、基于HTTP的服务。而SpringSecurity,则是用于...
在本教程中,我们将深入探讨如何使用Spring MVC、Spring和Hibernate三大框架进行全注解的整合开发。这个视频教程系列的第13部分,将帮助开发者掌握如何在Java Web项目中高效利用这些技术,实现一个现代化、高效且可...
通过整合Spring、Spring MVC和Hibernate,系统能够实现高效的数据管理、灵活的业务流程和强大的安全防护,为智能农业信息管理提供有力的技术支撑。在实际应用中,开发者可以根据农业场景的具体需求,对系统进行定制...
这个整合项目是基于Spring 3.0.5、Spring MVC 3和MyBatis 3.0.2版本,采用注解方式进行配置,简化了XML配置文件,提高了开发效率。 Spring MVC是Spring框架的一部分,主要负责Web请求的处理。在本项目中,通过注解...