说明:项目的总体结构,如下图
1. 下载Spring Security 3 下载地址:
http://static.springsource.org/spring-security/site/downloads.html2. 搭建Spring Security 3 的环境 解压后,如下图:
dist 文件夹中,是项目中所需要的jar文件,和两个Demo例子,Demo例子是用.war格式的文件给我们的。如图:
docs文件夹中,是Spring Security 3 的API和reference文档。
2.1 建立数据库和表(这里使用MySQL,数据库名demo)
Create table users ( username varchar(50), password varchar(50), enabled boolean )
注:密码是经过了md5加密的,插入数据的时候要注意 Create table authority( username varchar(50), authority varchar(50)
)
【建表语句丢了,这个肯定有问题,但是字段都是没问题的】 2.2 导入需要的jar包
1. 在MyEclipse中加入Spring的支持,版本什么都可以
2. 把刚刚加入的Spring的jar包都删掉,只保留
applicationContext.xml文件 3. 找到刚刚解压的Spring Security3 的包,在dist文件夹中找到那两
个.war的文件,随便找一个,把后缀名改为.rar 然后,然后解压出来,找到WEN-INF中lib文件夹,把其中所有的jar包都拷贝到Myeclipse的工程中。
2.3 配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 加载spring配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext*.xml</param-value> </context-param> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>[这个是一个代理,主要是代理Spring Security3 中的监听的Filter,刚开始的时候,在Spring的配置文件中如果没有配置bean,是会启动报错的,不过没问题,只需要处理下Spring的配置文件即可] </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 监听spring配置文件 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>[加载Spring的配置文件] <!-- 监听Session --> <listener> <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> </listener>[监听session是否过期] <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.azt.servlet.HelloServlet</servlet-class> </servlet> <servlet> <servlet-name>DocumentServlet</servlet-name> <servlet-class>com.azt.servlet.DocumentServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/HelloServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>DocumentServlet</servlet-name> <url-pattern>/DocumentServlet</url-pattern> </servlet-mapping>[这些是我用来做测试的servlet] <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
2.4 配置Spring的applicationcontext.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">[这个头文件是应该要注意的,一些版本信息和标签信息] <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8"></property> <property name="username" value="root"></property> <property name="password" value="admin"></property> </bean>[配置datasource,这个不用多说] <!-- 启用注解ANNOTATION <security:global-method-security secured-annotations="enabled" jsr250-annotations="enabled"></security:global-method-security> -->[通过启用Annotation来配置切点,(在业务不复杂的情况下,用这个是很方便的,但通常业务都是复杂的)] <!-- 配置切入点 --> <security:global-method-security> <!-- 第一个*,返回值的类型,可以是所有的类型, 第二个* ,包下的所有方法 --> <security:protect-pointcut access="ROLE_USER,ROLE_ADMIN" expression="execution(* com.azt.service.*.sayHello(..))"/> <!-- 第三个* ,所有已say开头的方法 --> <security:protect-pointcut access="ROLE_ADMIN" expression="execution(* com.azt.service.*.say*(..))"/> </security:global-method-security>[通过配置文件来配置切点] <security:http> <!-- 登录页面 --> <security:form-login login-page="/login.jsp" /> <security:logout logout-success-url="/login.jsp"/> <!-- 请求页面可能带一些参数 ,所以后面加*号,TIPS 要注意前面一定要根目录/--> <security:intercept-url pattern="/login.jsp*" filters="none" /> <security:intercept-url pattern="/admin.jsp*" access="ROLE_ADMIN,ROLE_MANAGER" /> <security:intercept-url pattern="/index.jsp*" access="ROLE_ADMIN,ROLE_USER,ROLE_MANAGER" /> <security:intercept-url pattern="/HelloServlet" [配置哪些角色可以进入哪些页面,在jsp的页面中也可以通过Spring Security的标签来控制不同的用户做的不同的操作]access="ROLE_ADMIN,ROLE_USER"/> <!-- 会话管理 --> <security:session-management invalid-session-url="/SessionTimeout.html"> <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true"[控制的session的失效,包括超时和重复登录] /> </security:session-management> </security:http> <security:authentication-manager> <security:authentication-provider> <security:password-encoder hash="md5"></security:password-encoder> <security:jdbc-user-service data-source-ref="datasource" />[密码通过md5加密] </security:authentication-provider> </security:authentication-manager> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="classpath:messages_zh_CN"></property> </bean> <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy"> <security:filter-chain-map path-type="ant"> <security:filter-chain pattern="/webServices/**" filters="securityContextPersistentceFilterWithASCFalse, basicAuthenticationFilter, exceptionTranslationFilter, filterSecurityInterceptor"/> <security:filter-chain pattern="/**" filters="securityContextPersistenceFilterWithASCFalse, formLoginFilter, exceptionTranslationFilter, filterSecurityInterception"/> </security:filter-chain-map> </bean>[核心,这是配置Spring Security中的filter链] <!-- 业务方法 --> <bean id="helloService" class="com.azt.service.impl.HelloServiceImpl"></bean>
配置login.jsp <body> <h3>用户登录</h3> ${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message } <form action="${pageContext.request.contextPath}/j_spring_security_check" method="post"> 用户名:<input type="text" name="j_username"></input><br/> 密 码:<input type="password" name="j_password"></input><br/> <input type="submit" value="登录"></input> </form> </body> 配置index.jsp 引入标签: <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> Body部分 <body> <h1>首页</h1> 欢迎您<sec:authentication property="name"></sec:authentication>!!!!!!!!!!!<br/> <sec:authorize ifAllGranted="ROLE_ADMIN">[只有ROLE_ADMIN权限才看到这些东西] <a href="admin.jsp">进入admin.jsp页面!</a><br/> <hr/> <a href="DocumentServlet?method=add">新增文档</a><br /> <a href="DocumentServlet?method=update">更新文档</a><br /> <a href="DocumentServlet?method=delete">删除文档</a><br /> </sec:authorize> <sec:authorize ifAllGranted="ROLE_MANAGER">[只有ROLE_MANAGER权限才能看到这些东西] <a href="admin.jsp">进入admin.jsp页面!</a><br/> <hr/> <a href="DocumentServlet?method=update">更新文档</a><br /> <a href="DocumentServlet?method=add">新增文档</a><br /> </sec:authorize> <a href="DocumentServlet?method=find">查看文档</a> <br/> <hr></hr> <a href="HelloServlet?method=sayHello&name=<sec:authentication property="name"/>">问好</a><br/> <a href="HelloServlet?method=sayBye&name=<sec:authentication property="name"/>">再见</a><br/> <hr /> <a href="j_spring_security_logout">退出系统</a> </body> SessinTimeout页面 <body> <h1>您的会话超时了!!!!!!!!</h1> </body>
总结:
以上的配置都是通过Spring Security 3 框架的Filter Chain 来实现的,这个项目中并没有自定义自己的Filter,在实际的项目中也是能满足绝大部分的需求的。对Spring Security 的看法: Spring Security 确实是个很强大的框架,功能很完善,但就是配置还是有点复杂!