使用spring-security3.1 + spring mvc + Hibernate 控制系统权限

来源:互联网 发布:tensorflow cuda 编辑:程序博客网 时间:2024/05/24 02:40


第一步

下载spring-security3.1

解压后进入dist目录,里面有两个war文件,解压其中一个。

然后将里面的jar包全部复制到项目中。

官方中文文档下载地址:http://www.asdtiang.org/wp-content/uploads/2011/09/Spring-Security-3.0.1-%E4%B8%AD%E6%96%87%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3.pdf

 

第二步

配置web.xml spring的监听器, 以及spring-mvc的监听器

<?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"><display-name></display-name><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><context-param><param-name>contextConfigLocation</param-name><param-value>          classpath*:applicationContext.xml,        </param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param>            <param-name>contextConfigLocation</param-name>            <param-value>classpath*:spring-mvc.xml</param-value>          </init-param>  <load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>*.action</url-pattern></servlet-mapping></web-app>

加入applicationContext.xml与spring-mvc.xml到src目录

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd              http://www.springframework.org/schema/context              http://www.springframework.org/schema/context/spring-context-3.0.xsd              http://www.springframework.org/schema/mvc               http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"><!-- 启用注解方式 --><context:annotation-config /><context:component-scan base-package="com.zf" /><!-- 启用mvc注解 --><mvc:annotation-driven /></beans>  

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><!-- 视图解析器 --><bean id="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" /></beans>  


第三步

加入spring-security.xml配置文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:security="http://www.springframework.org/schema/security"xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"><!--use-expressions="true" 的意思是开启表达式 access-denied-page的意思是,当验证权限失败后会跳转到的页面  --><security:http auto-config="true" use-expressions="true" access-denied-page="/auth/denied" ></security:http><!-- 配置一个认证管理器 --><security:authentication-manager><security:authentication-provider><security:user-service><!-- 这样的配置表示向系统中添加了一个用户 用户名和密码都为admin ,并且该用户拥有ROLE_USER角色(角色可以用逗号隔开) --><security:user name="admin" password="admin" authorities="ROLE_USER"/></security:user-service></security:authentication-provider></security:authentication-manager></beans>



第四步

在web.xml中配置SpringSecurity拦截器(如果不先进行第三步的配置,下面配置完之后,tomcat启动会报错)

<!-- 配置SpringSecurity --><filter><filter-name>springSecurityFilterChain</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>springSecurityFilterChain</filter-name><url-pattern>/*</url-pattern></filter-mapping>


好了,现在已经配置完成,tomcat已经可以启动了。但是还没有配置具体的权限策略。


第五步

配置Hibernate

在applicationContext.xml中配置JPA

<!-- 开启注解事物 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />  <!-- 配置hibernate --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">            <!-- 指定连接数据库的驱动 -->            <property name="driverClass" value="com.mysql.jdbc.Driver"/>            <!-- 指定连接数据库的URL -->            <property name="jdbcUrl" value="jdbc:mysql:///spring-scurity"/>            <!-- 指定连接数据库的用户名 -->            <property name="user" value="root"/>            <!-- 指定连接数据库的密码 -->            <property name="password" value="root"/>            <!-- 指定连接数据库连接池的最大连接数 -->            <property name="maxPoolSize" value="20"/>            <!-- 指定连接数据库连接池的最小连接数 -->            <property name="minPoolSize" value="1"/>            <!-- 指定连接数据库连接池的初始化连接数 -->            <property name="initialPoolSize" value="1"/>            <!-- 指定连接数据库连接池的连接的最大空闲时间 -->            <property name="maxIdleTime" value="20"/>         </bean>             <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >              <property name="dataSource" ref="dataSource"></property>              <property name="hibernateProperties">                  <props>                      <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>                      <prop key="hibernate.show_sql">true</prop>                      <prop key="hibernate.query.substitutions">true 1,false 0</prop>                      <prop key="hibernate.hbm2ddl.auto">update</prop>                  </props>              </property>              <property name="packagesToScan">                  <list>                      <value>com.zf.pojo</value>                   </list>              </property>           </bean>            <!-- 事务管理器 -->      <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">          <property name="sessionFactory" ref="sessionFactory"></property>      </bean>    

第六步

编写实体类与DAO

package com.zf.pojo;import java.util.ArrayList;import java.util.Date;import java.util.List;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.ManyToMany;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;@Entity@Table(name = "etuser")public class ETUser {@Id@GeneratedValue(strategy = GenerationType.AUTO)private int id ;private String username ;private String password ;private int age ;@ManyToMany@JoinTable(name="user_role" , joinColumns = {@JoinColumn(name = "userid")}, inverseJoinColumns = {@JoinColumn(name="roleid")}) private List<ETRole> roles = new ArrayList<ETRole>();  @Temporal(TemporalType.DATE)private Date regDate ;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Date getRegDate() {return regDate;}public void setRegDate(Date regDate) {this.regDate = regDate;}public List<ETRole> getRoles() {return roles;}public void setRoles(List<ETRole> roles) {this.roles = roles;}}


package com.zf.pojo;import java.util.ArrayList;import java.util.List;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.ManyToMany;import javax.persistence.Table;@Entity@Table(name = "etrole")public class ETRole {@Id@GeneratedValue(strategy = GenerationType.AUTO)private int id;private String roleCode ;private String despripe ;@ManyToMany@JoinTable(name="user_role" , joinColumns = {@JoinColumn(name = "roleid")}, inverseJoinColumns = {@JoinColumn(name="userid")}) private List<ETUser> users = new ArrayList<ETUser>();public int getId() {return id;}public void setId(int id) {this.id = id;}public String getRoleCode() {return roleCode;}public void setRoleCode(String roleCode) {this.roleCode = roleCode;}public String getDespripe() {return despripe;}public void setDespripe(String despripe) {this.despripe = despripe;}public List<ETUser> getUsers() {return users;}public void setUsers(List<ETUser> users) {this.users = users;}}


package com.zf.dao;import java.util.List;import javax.annotation.Resource;import org.hibernate.SessionFactory;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.zf.pojo.ETUser;@Service("UserDao")@Transactional(propagation = Propagation.REQUIRED)public class UserDao extends HibernateDaoSupport{/** * 根据用户名查询用户 * @param username * @return */@SuppressWarnings("unchecked")public ETUser findUserByUserName(String username){List<ETUser> result =  getHibernateTemplate().find("from ETUser e where e.username = ?", username );if(result != null && !result.isEmpty())    return result.get(0);return null ;}/** * 根据用户名和密码查询用户 * @param username * @param password * @return */@SuppressWarnings("unchecked")public ETUser findUserBuNameAndPwd(String username , String password){List<ETUser> result =  getHibernateTemplate().find("from ETUser e where e.username = ? and e.password = ?", username , password);if(result != null && !result.isEmpty())  return result.get(0);return null ;}@Resource(name = "sessionFactory")public void setMySessionFactory(SessionFactory sessionFactory){super.setSessionFactory(sessionFactory);}}



下面来配置使用数据库中的用户。.

编写处理用户信息的UserDetailsService实现类

package com.zf.service;import java.util.ArrayList;import java.util.Collection;import java.util.List;import javax.annotation.Resource;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.GrantedAuthorityImpl;import org.springframework.security.core.userdetails.User;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import org.springframework.stereotype.Repository;import com.zf.dao.UserDao;import com.zf.pojo.ETRole;import com.zf.pojo.ETUser;/** * 该类用户从数据库获取用户信息和用户权限信息 提供给spring-security使用 * @author Administrator * */@Repository("ETUserDetailService")public class ETUserDetailService implements UserDetailsService{@Resource(name = "UserDao")private UserDao userdao ;public UserDetails loadUserByUsername(String username)throws UsernameNotFoundException {ETUser etuser = userdao.findUserByUserName(username);UserDetails user = null ;if(etuser != null){user = new User(username, etuser.getPassword(), true,true , true,true,findUserAuthorities(etuser) );}return user;}/** * 获取用户的权限 * @param user * @return */@SuppressWarnings("deprecation")public Collection<GrantedAuthority> findUserAuthorities(ETUser user){List<GrantedAuthority> autthorities = new ArrayList<GrantedAuthority>();List<ETRole> roles =  user.getRoles();System.out.println(roles.size());for (ETRole etRole : roles) {autthorities.add(new GrantedAuthorityImpl(etRole.getRoleCode()));}return autthorities ;}}


配置spring-security.xml 。

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:security="http://www.springframework.org/schema/security"xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"><!--use-expressions="true" 的意思是开启表达式 access-denied-page的意思是,当验证权限失败后会跳转到的页面  --><security:http auto-config="true" use-expressions="true" access-denied-page="/powermiss.jsp" ><!-- 对登录页面,所有的用户都可以访问 --><security:intercept-url pattern="/login.jsp"  access="permitAll" /><!-- 对所有的资源,都必须要有ROLE_USER角色的用户 才可以访问 --><security:intercept-url pattern="/*"  access="hasRole('ADMIN')" /><!-- 配置登录页面为login.jsp ,登录成功默认跳转到index.jsp,登录失败返回login.jsp并携带参数error=true --><security:form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true" /></security:http><!-- 配置一个认证管理器 --><security:authentication-manager><!-- 使用自定义的UserDetailService  --><security:authentication-provider user-service-ref="ETUserDetailService"><!-- 下面的内容就可注释掉了 --><!-- <security:user-service> --><!-- 这样的配置表示向系统中添加了一个用户 用户名和密码都为admin ,并且该用户拥有ROLE_USER角色(角色可以用逗号隔开) --><!-- <security:user name="admin" password="admin" authorities="ROLE_USER"/> --><!-- </security:user-service> --></security:authentication-provider></security:authentication-manager></beans>

web.mvc 中配置openSessionInView

<filter><filter-name>openSessionInView</filter-name><filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class><init-param><param-name>singleSession</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>openSessionInView</filter-name><url-pattern>*.action</url-pattern></filter-mapping><!-- 如果配置opensessionInView ,别忘了给login的action也加上 --><filter-mapping><filter-name>openSessionInView</filter-name><url-pattern>/j_spring_security_check</url-pattern></filter-mapping>


spring-mvc.xml 中配置OpenSessionInView 

<!-- 处理在类级别上的@RequestMapping注解 --><beanclass="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"><property name="interceptors">        <!-- 配置过滤器 --><list><ref bean="openSessionInView" /></list></property></bean><!-- 将OpenSessionInView 打开 --><bean id="openSessionInView"class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"><property name="sessionFactory" ref="sessionFactory"></property></bean>


编写测试用的页面。

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>  <body>    <h3>用户登录</h3>    <!-- from的action地址,以及用户名密码的name 。都是spring-security固定的。 -->    <form action="<%=basePath %>j_spring_security_check" method="post">              <p>              <label for="j_username">Username</label> <input id="j_username"                  name="j_username" type="text" />          </p>            <p>              <label for="j_password">Password</label> <input id="j_password"                  name="j_password" type="password" />          </p>            <input type="submit" value="Login" />        </form>        </body></html>

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>         <body>         <h3>登录成功,欢迎您:<sec:authentication property="name" /></h3>        <a href="<%=basePath%>admin.jsp">进入管理员页面</a>  <a href="<%=basePath%>vip.jsp">进入会员页面</a>  <a href="<%=basePath%>auth/logout">注销</a>    </body></html>

admin.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>    <body>    <h3>管理员页面</h3>  </body></html>


<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>    <body>    <h3>会员页面</h3>      </body></html>


powermiss.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'powermiss.jsp' starting page</title>    <meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>    <body>    <h1 style="color: red;">对不起,您无权访问该资源!</h1>    </body></html>

重新配置spring-security.xml 中各资源的权限

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:security="http://www.springframework.org/schema/security"xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"><!--use-expressions="true" 的意思是开启表达式 access-denied-page的意思是,当验证权限失败后会跳转到的页面  --><security:http auto-config="true" use-expressions="true" access-denied-page="/powermiss.jsp" ><!-- 对登录页面,所有的用户都可以访问 --><security:intercept-url pattern="/login.jsp*"  access="permitAll" /><security:intercept-url pattern="/vip.jsp*"  access="hasRole('VIP')" /><security:intercept-url pattern="/admin.jsp*"  access="hasRole('ADMIN')" /><!-- 对所有的资源,都必须要有COMM权限 才可以访问 --><security:intercept-url pattern="/*"  access="hasRole('COMM')" /><!-- 配置登录页面为login.jsp ,登录成功默认跳转到index.jsp,登录失败返回login.jsp并携带参数error=true --><security:form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true" /><!-- 退出配置 --><security:logout invalidate-session="true" logout-success-url="/login.jsp" logout-url="/auth/logout"/></security:http><!-- 配置一个认证管理器 --><security:authentication-manager><!-- 使用自定义的UserDetailService  --><security:authentication-provider user-service-ref="ETUserDetailService"><!-- 下面的内容就可注释掉了 --><!-- <security:user-service> --><!-- 这样的配置表示向系统中添加了一个用户 用户名和密码都为admin ,并且该用户拥有ROLE_USER角色(角色可以用逗号隔开) --><!-- <security:user name="admin" password="admin" authorities="ROLE_USER"/> --><!-- </security:user-service> --></security:authentication-provider></security:authentication-manager></beans>

向数据库中添加测试数据。



然后就可以测试访问了。



使用注解方式对指定的方法进行权限控制

AdminService.java

package com.zf.service;import javax.annotation.security.RolesAllowed;import org.springframework.security.access.prepost.PreAuthorize;public interface AdminService {/* 拥有 Admin 权限才能的方法 ,必须定义在接口上面*/  @PreAuthorize("hasRole('ADMIN')")public String test01() ;    @RolesAllowed({"ADMIN"})public String test02();/* 上面的两种注解都可以 */}


AdminServiceImpl.java
package com.zf.service;import org.springframework.stereotype.Service;@Service("AdminServiceImpl")public class AdminServiceImpl implements AdminService{   public String test01(){    System.out.println("方法test01被Admin用户调用");return "success";}public String test02() {System.out.println("方法test02被Admin用户调用");return "success";}}

package com.zf.control;import javax.annotation.Resource;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import com.zf.service.AdminService;@Controller@RequestMapping("/admin/")@Scope("request")public class AdminController {    @Resource(name = "AdminServiceImpl")private AdminService adminService;@RequestMapping(value = "test01")public ModelAndView test01(){ModelAndView mav = new ModelAndView("admin");  System.out.println(adminService.test01());return mav ;}@RequestMapping(value = "test02")public ModelAndView test02(){ModelAndView mav = new ModelAndView("admin");  System.out.println(adminService.test01());return mav ;}}

向index.jsp中添加两个链接

<a href="<%=basePath%>admin/test01.action">/admin/test01</a>
  <a href="<%=basePath%>admin/test02.action">/admin/test02</a>


现在就可以测试了。



在jsp页面使用security标签需要引入<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>库


如果是使用freemarker ,配置方法见 http://blog.sina.com.cn/s/blog_55bba7c10100h5bz.html



其他功能

在http标签内配置

<!-- 配置session失效之后跳转到的页面 session-authentication-error-url指向的是登录被限制后跳转到的页面 --><security:session-management invalid-session-url="/sessiontimeout.jsp"  session-authentication-error-url="/loginerror.jsp"><!-- 配置一个帐号同时只能有一个会话,这样当有第二个用户登录的时候,第一个用户就会失效 --><security:concurrency-control max-sessions="1" /><!-- 配置一个帐号同时智能有一个会话 ,并且第第二个尝试登录的账户不能让他登录,然后跳转到session-authentication-error-url指向的页面--><security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true"   /></security:session-management>


配置登录验证码实例:

写一个VolidateAuthCodeUsernamePasswordAuthenticationFilter继承UsernamePasswordAuthenticationFilter用于验证用户登录

package com.zf.myfilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.security.core.Authentication;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;/** * 扩展UsernamePasswordAuthenticationFilter加上验证码的功能 *    * @author Administrator * */public class VolidateAuthCodeUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{@Overridepublic Authentication attemptAuthentication(HttpServletRequest request,HttpServletResponse response) throws AuthenticationException {System.out.println("进入了VolidateAuthCodeUsernamePasswordAuthenticationFilter" + request.getParameter("j_username"));//这里可以进行验证验证码的操作return super.attemptAuthentication(request, response);}}

需要配置一个LoginUrlAuthenticationEntryPoint bean

<bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"><property name="loginFormUrl" value="/login.jsp"></property></bean>

配置过滤器bean

<!-- 验证码过滤器 --><bean id="validateCodeAuthenticationFilter"class="com.zf.myfilter.VolidateAuthCodeUsernamePasswordAuthenticationFilter"><property name="authenticationSuccessHandler"ref="loginLogAuthenticationSuccessHandler"></property><property name="authenticationFailureHandler"ref="simpleUrlAuthenticationFailureHandler"></property><property name="authenticationManager" ref="authenticationManager"></property></bean><!-- 登录成功 --><bean id="loginLogAuthenticationSuccessHandler"class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"><property name="defaultTargetUrl" value="/index.jsp"></property></bean><!-- 登录失败 --><bean id="simpleUrlAuthenticationFailureHandler"class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"><property name="defaultFailureUrl" value="/index.jsp?error=true"></property></bean>

将 <http> 中的auto-config 属性删除。加上 entry-point-ref="authenticationProcessingFilterEntryPoint" 属性

并将<form-login> 删除,使用<security:custom-filter
ref="validateCodeAuthenticationFilter"  position="FORM_LOGIN_FILTER"
/> 替代 FORM_LOGIN_FILTER拦截器


完整的spring-security.xml 配置如下:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security"xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"><!-- 启用注解方式对方法的权限控制 --><security:global-method-securitypre-post-annotations="enabled" secured-annotations="enabled"jsr250-annotations="enabled" proxy-target-class="true"><security:protect-pointcut access="VIP"expression="execution(* com.zf.service.VipService.*(..))" /></security:global-method-security><!--use-expressions="true" 的意思是开启表达式 access-denied-page的意思是,当验证权限失败后会跳转到的页面 --><security:http use-expressions="true" access-denied-page="/powermiss.jsp" entry-point-ref="authenticationProcessingFilterEntryPoint"><!-- 对登录页面,所有的用户都可以访问 --><security:intercept-url pattern="/login.jsp*"access="permitAll" /><security:intercept-url pattern="/vip.jsp*"access="hasRole('VIP')" /><security:intercept-url pattern="/admin.jsp*"access="hasRole('ADMIN')" /><!-- 对所有的资源,都必须要有COMM权限 才可以访问 -->  <security:intercept-url pattern="/*"access="hasRole('COMM')" /><!-- 使用自己的过滤器 --><!-- 下面的配置表示将自己的过滤器放在FORM_LOGIN_FILTER过滤链的最前面(可以这样来验证登录验证码) --><security:custom-filterref="validateCodeAuthenticationFilter"  position="FORM_LOGIN_FILTER" /><!-- 配置登录页面为login.jsp ,登录成功默认跳转到index.jsp,登录失败返回login.jsp并携带参数error=true --><!-- <security:form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true" />  --><!-- 退出配置 --><security:logout invalidate-session="true"logout-success-url="/login.jsp" logout-url="/auth/logout" /></security:http><bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"><property name="loginFormUrl" value="/login.jsp"></property></bean><!-- 验证码过滤器 --><bean id="validateCodeAuthenticationFilter"class="com.zf.myfilter.VolidateAuthCodeUsernamePasswordAuthenticationFilter"><property name="authenticationSuccessHandler"ref="loginLogAuthenticationSuccessHandler"></property><property name="authenticationFailureHandler"ref="simpleUrlAuthenticationFailureHandler"></property><property name="authenticationManager" ref="authenticationManager"></property></bean><!-- 登录成功 --><bean id="loginLogAuthenticationSuccessHandler"class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"><property name="defaultTargetUrl" value="/index.jsp"></property></bean><!-- 登录失败 --><bean id="simpleUrlAuthenticationFailureHandler"class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"><property name="defaultFailureUrl" value="/index.jsp?error=true"></property></bean><!-- 配置一个认证管理器 --><security:authentication-manager alias="authenticationManager"><!-- 使用自定义的UserDetailService --><security:authentication-provideruser-service-ref="ETUserDetailService"><!-- 下面的内容就可注释掉了 --><!-- <security:user-service> --><!-- 这样的配置表示向系统中添加了一个用户 用户名和密码都为admin ,并且该用户拥有ROLE_USER角色(角色可以用逗号隔开) --><!-- <security:user name="admin" password="admin" authorities="ROLE_USER"/> --><!-- </security:user-service> --></security:authentication-provider></security:authentication-manager></beans>




SPEL 表达式 

//拥有DISUSER_PUBLISH_ROOM一个权限就可以访问//@PreAuthorize("hasRole('DISUSER_PUBLISH_ROOM')")//拥有DISUSER_PUBLISH_ROOM、DISUSER_MODIFY_ROOM中任意一个权限即可访问@PreAuthorize("hasAnyRole('DISUSER_PUBLISH_ROOM','DISUSER_ADMIN')") // or//@PreAuthorize("hasRole('DISUSER_PUBLISH_ROOM') or hasRole('DISUSER_MODIFY_ROOM')")//必须同时拥有DISUSER_PUBLISH_ROOM、DISUSER_MODIFY_ROOM两个权限才可以访问    //@PreAuthorize("hasRole('DISUSER_PUBLISH_ROOM') and hasRole('DISUSER_MODIFY_ROOM')")





未完待续》。。