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

第一步

下载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的监听器

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  5.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  6.     <display-name></display-name>  
  7.     <welcome-file-list>  
  8.         <welcome-file>index.jsp</welcome-file>  
  9.     </welcome-file-list>  
  10.   
  11.     <context-param>  
  12.         <param-name>contextConfigLocation</param-name>  
  13.         <param-value>    
  14.         classpath*:applicationContext.xml,  
  15.         </param-value>  
  16.     </context-param>  
  17.   
  18.     <listener>  
  19.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  20.     </listener>  
  21.       
  22.     <servlet>  
  23.         <servlet-name>springmvc</servlet-name>  
  24.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  25.         <init-param>    
  26.           <param-name>contextConfigLocation</param-name>    
  27.           <param-value>classpath*:spring-mvc.xml</param-value>    
  28.         </init-param>    
  29.         <load-on-startup>1</load-on-startup>  
  30.     </servlet>  
  31.       
  32.     <servlet-mapping>  
  33.         <servlet-name>springmvc</servlet-name>  
  34.         <url-pattern>*.action</url-pattern>  
  35.     </servlet-mapping>  
  36.       
  37.       
  38. </web-app>  

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

applicationContext.xml

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:mvc="http://www.springframework.org/schema/mvc"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans     
  6.             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
  7.             http://www.springframework.org/schema/context    
  8.             http://www.springframework.org/schema/context/spring-context-3.0.xsd    
  9.             http://www.springframework.org/schema/mvc     
  10.             http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
  11.     <!-- 启用注解方式 -->  
  12.     <context:annotation-config />  
  13.       
  14.     <context:component-scan base-package="com.zf" />  
  15.       
  16.     <!-- 启用mvc注解 -->  
  17.     <mvc:annotation-driven />  
  18.       
  19. </beans>    

spring-mvc.xml

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans     
  5.             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  6.   
  7.     <!-- 视图解析器 -->  
  8.     <bean id="viewResolver"  
  9.         class="org.springframework.web.servlet.view.InternalResourceViewResolver"  
  10.         p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />  
  11.           
  12.   
  13. </beans>    


第三步

加入spring-security.xml配置文件

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  4.     xmlns:security="http://www.springframework.org/schema/security"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  6.             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  7.             http://www.springframework.org/schema/security   
  8.             http://www.springframework.org/schema/security/spring-security-3.1.xsd">  
  9.       
  10.     <!--use-expressions="true" 的意思是开启表达式 access-denied-page的意思是,当验证权限失败后会跳转到的页面  -->  
  11.     <security:http auto-config="true" use-expressions="true" access-denied-page="/auth/denied" >  
  12.       
  13.     </security:http>  
  14.       
  15.     <!-- 配置一个认证管理器 -->  
  16.     <security:authentication-manager>  
  17.         <security:authentication-provider>  
  18.             <security:user-service>  
  19.                 <!-- 这样的配置表示向系统中添加了一个用户 用户名和密码都为admin ,并且该用户拥有ROLE_USER角色(角色可以用逗号隔开) -->  
  20.                 <security:user name="admin" password="admin" authorities="ROLE_USER"/>  
  21.             </security:user-service>  
  22.         </security:authentication-provider>  
  23.     </security:authentication-manager>  
  24.       
  25. </beans>  



第四步

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

[html] view plain copy
  1. <!-- 配置SpringSecurity -->  
  2.     <filter>  
  3.         <filter-name>springSecurityFilterChain</filter-name>  
  4.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  5.     </filter>  
  6.   
  7.     <filter-mapping>  
  8.         <filter-name>springSecurityFilterChain</filter-name>  
  9.         <url-pattern>/*</url-pattern>  
  10.     </filter-mapping>  
  11.       


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


第五步

配置Hibernate

在applicationContext.xml中配置JPA

[java] view plain copy
  1. <span>  </span><!-- 开启注解事物 -->  
  2. <span>  </span> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />    
  3. <span>  </span>  
  4. <span>  </span><!-- 配置hibernate -->  
  5. <span>  </span><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">       
  6.        <!-- 指定连接数据库的驱动 -->       
  7.        <property name="driverClass" value="com.mysql.jdbc.Driver"/>       
  8.        <!-- 指定连接数据库的URL -->       
  9.        <property name="jdbcUrl" value="jdbc:mysql:///spring-scurity"/>       
  10.        <!-- 指定连接数据库的用户名 -->       
  11.        <property name="user" value="root"/>       
  12.        <!-- 指定连接数据库的密码 -->       
  13.        <property name="password" value="root"/>       
  14.        <!-- 指定连接数据库连接池的最大连接数 -->       
  15.        <property name="maxPoolSize" value="20"/>       
  16.        <!-- 指定连接数据库连接池的最小连接数 -->       
  17.        <property name="minPoolSize" value="1"/>       
  18.        <!-- 指定连接数据库连接池的初始化连接数 -->       
  19.        <property name="initialPoolSize" value="1"/>       
  20.        <!-- 指定连接数据库连接池的连接的最大空闲时间 -->       
  21.        <property name="maxIdleTime" value="20"/>       
  22.     </bean>     
  23.         
  24.     <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >    
  25.             <property name="dataSource" ref="dataSource"></property>    
  26.             <property name="hibernateProperties">    
  27.                 <props>    
  28.                     <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>    
  29.                     <prop key="hibernate.show_sql">true</prop>    
  30.                     <prop key="hibernate.query.substitutions">true 1,false 0</prop>    
  31.                     <prop key="hibernate.hbm2ddl.auto">update</prop>    
  32.                 </props>    
  33.             </property>    
  34.             <property name="packagesToScan">    
  35.                 <list>    
  36.                     <value>com.zf.pojo</value>     
  37.                 </list>    
  38.             </property>         
  39.     </bean>    
  40.         
  41.     <!-- 事务管理器 -->    
  42.     <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">    
  43.         <property name="sessionFactory" ref="sessionFactory"></property>    
  44.     </bean>    
  45.     

第六步

编写实体类与DAO

[java] view plain copy
  1. package com.zf.pojo;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Date;  
  5. import java.util.List;  
  6.   
  7. import javax.persistence.Entity;  
  8. import javax.persistence.GeneratedValue;  
  9. import javax.persistence.GenerationType;  
  10. import javax.persistence.Id;  
  11. import javax.persistence.JoinColumn;  
  12. import javax.persistence.JoinTable;  
  13. import javax.persistence.ManyToMany;  
  14. import javax.persistence.Table;  
  15. import javax.persistence.Temporal;  
  16. import javax.persistence.TemporalType;  
  17.   
  18. @Entity  
  19. @Table(name = "etuser")  
  20. public class ETUser {  
  21.   
  22.     @Id  
  23.     @GeneratedValue(strategy = GenerationType.AUTO)  
  24.     private int id ;  
  25.       
  26.     private String username ;  
  27.       
  28.     private String password ;  
  29.       
  30.     private int age ;  
  31.       
  32.     @ManyToMany  
  33.     @JoinTable(name="user_role" , joinColumns = {  
  34.             @JoinColumn(name = "userid")  
  35.     }, inverseJoinColumns = {@JoinColumn(name="roleid")})   
  36.     private List<ETRole> roles = new ArrayList<ETRole>();    
  37.       
  38.     @Temporal(TemporalType.DATE)  
  39.     private Date regDate ;  
  40.   
  41.     public int getId() {  
  42.         return id;  
  43.     }  
  44.   
  45.     public void setId(int id) {  
  46.         this.id = id;  
  47.     }  
  48.   
  49.     public String getUsername() {  
  50.         return username;  
  51.     }  
  52.   
  53.     public void setUsername(String username) {  
  54.         this.username = username;  
  55.     }  
  56.   
  57.     public String getPassword() {  
  58.         return password;  
  59.     }  
  60.   
  61.     public void setPassword(String password) {  
  62.         this.password = password;  
  63.     }  
  64.   
  65.     public int getAge() {  
  66.         return age;  
  67.     }  
  68.   
  69.     public void setAge(int age) {  
  70.         this.age = age;  
  71.     }  
  72.   
  73.     public Date getRegDate() {  
  74.         return regDate;  
  75.     }  
  76.   
  77.     public void setRegDate(Date regDate) {  
  78.         this.regDate = regDate;  
  79.     }  
  80.   
  81.     public List<ETRole> getRoles() {  
  82.         return roles;  
  83.     }  
  84.   
  85.     public void setRoles(List<ETRole> roles) {  
  86.         this.roles = roles;  
  87.     }  
  88.       
  89.       
  90. }  


[java] view plain copy
  1. package com.zf.pojo;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import javax.persistence.Entity;  
  7. import javax.persistence.GeneratedValue;  
  8. import javax.persistence.GenerationType;  
  9. import javax.persistence.Id;  
  10. import javax.persistence.JoinColumn;  
  11. import javax.persistence.JoinTable;  
  12. import javax.persistence.ManyToMany;  
  13. import javax.persistence.Table;  
  14.   
  15. @Entity  
  16. @Table(name = "etrole")  
  17. public class ETRole {  
  18.   
  19.     @Id  
  20.     @GeneratedValue(strategy = GenerationType.AUTO)  
  21.     private int id;  
  22.       
  23.     private String roleCode ;  
  24.       
  25.     private String despripe ;  
  26.       
  27.       
  28.     @ManyToMany  
  29.     @JoinTable(name="user_role" , joinColumns = {  
  30.             @JoinColumn(name = "roleid")  
  31.     }, inverseJoinColumns = {@JoinColumn(name="userid")})   
  32.     private List<ETUser> users = new ArrayList<ETUser>();  
  33.   
  34.     public int getId() {  
  35.         return id;  
  36.     }  
  37.   
  38.     public void setId(int id) {  
  39.         this.id = id;  
  40.     }  
  41.   
  42.     public String getRoleCode() {  
  43.         return roleCode;  
  44.     }  
  45.   
  46.     public void setRoleCode(String roleCode) {  
  47.         this.roleCode = roleCode;  
  48.     }  
  49.   
  50.     public String getDespripe() {  
  51.         return despripe;  
  52.     }  
  53.   
  54.     public void setDespripe(String despripe) {  
  55.         this.despripe = despripe;  
  56.     }  
  57.   
  58.     public List<ETUser> getUsers() {  
  59.         return users;  
  60.     }  
  61.   
  62.     public void setUsers(List<ETUser> users) {  
  63.         this.users = users;  
  64.     }  
  65.   
  66.       
  67. }  


[java] view plain copy
  1. package com.zf.dao;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.annotation.Resource;  
  6.   
  7. import org.hibernate.SessionFactory;  
  8. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;  
  9. import org.springframework.stereotype.Service;  
  10. import org.springframework.transaction.annotation.Propagation;  
  11. import org.springframework.transaction.annotation.Transactional;  
  12.   
  13. import com.zf.pojo.ETUser;  
  14.   
  15. @Service("UserDao")  
  16. @Transactional(propagation = Propagation.REQUIRED)  
  17. public class UserDao extends HibernateDaoSupport{  
  18.       
  19.       
  20.     /** 
  21.      * 根据用户名查询用户 
  22.      * @param username 
  23.      * @return 
  24.      */  
  25.     @SuppressWarnings("unchecked")  
  26.     public ETUser findUserByUserName(String username){  
  27.         List<ETUser> result =  getHibernateTemplate().find("from ETUser e where e.username = ?"  
  28.                 , username );  
  29.         if(result != null && !result.isEmpty())      
  30.             return result.get(0);  
  31.         return null ;  
  32.     }  
  33.   
  34.     /** 
  35.      * 根据用户名和密码查询用户 
  36.      * @param username 
  37.      * @param password 
  38.      * @return 
  39.      */  
  40.     @SuppressWarnings("unchecked")  
  41.     public ETUser findUserBuNameAndPwd(String username , String password){  
  42.         List<ETUser> result =  getHibernateTemplate().find("from ETUser e where e.username = ? and e.password = ?"  
  43.                 , username , password);  
  44.         if(result != null && !result.isEmpty())    
  45.             return result.get(0);  
  46.         return null ;  
  47.     }  
  48.       
  49.     @Resource(name = "sessionFactory")  
  50.     public void setMySessionFactory(SessionFactory sessionFactory){  
  51.         super.setSessionFactory(sessionFactory);  
  52.     }  
  53.   
  54.   
  55. }  



[java] view plain copy
  1.   

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

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

[java] view plain copy
  1. package com.zf.service;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Collection;  
  5. import java.util.List;  
  6.   
  7. import javax.annotation.Resource;  
  8.   
  9. import org.springframework.security.core.GrantedAuthority;  
  10. import org.springframework.security.core.authority.GrantedAuthorityImpl;  
  11. import org.springframework.security.core.userdetails.User;  
  12. import org.springframework.security.core.userdetails.UserDetails;  
  13. import org.springframework.security.core.userdetails.UserDetailsService;  
  14. import org.springframework.security.core.userdetails.UsernameNotFoundException;  
  15. import org.springframework.stereotype.Repository;  
  16.   
  17. import com.zf.dao.UserDao;  
  18. import com.zf.pojo.ETRole;  
  19. import com.zf.pojo.ETUser;  
  20.   
  21. /** 
  22.  * 该类用户从数据库获取用户信息和用户权限信息 提供给spring-security使用 
  23.  * @author Administrator 
  24.  * 
  25.  */  
  26. @Repository("ETUserDetailService")  
  27. public class ETUserDetailService implements UserDetailsService{  
  28.   
  29.     @Resource(name = "UserDao")  
  30.     private UserDao userdao ;  
  31.       
  32.     public UserDetails loadUserByUsername(String username)  
  33.             throws UsernameNotFoundException {  
  34.         ETUser etuser = userdao.findUserByUserName(username);  
  35.         UserDetails user = null ;  
  36.         if(etuser != null){  
  37.             user = new User(username, etuser.getPassword(), true,  
  38.                     true ,   
  39.                     true,  
  40.                     true,findUserAuthorities(etuser) );  
  41.         }  
  42.           
  43.         return user;  
  44.     }  
  45.   
  46.     /** 
  47.      * 获取用户的权限 
  48.      * @param user 
  49.      * @return 
  50.      */  
  51.     @SuppressWarnings("deprecation")  
  52.     public Collection<GrantedAuthority> findUserAuthorities(ETUser user){  
  53.         List<GrantedAuthority> autthorities = new ArrayList<GrantedAuthority>();  
  54.         List<ETRole> roles =  user.getRoles();  
  55.         System.out.println(roles.size());  
  56.         for (ETRole etRole : roles) {  
  57.             autthorities.add(new GrantedAuthorityImpl(etRole.getRoleCode()));  
  58.         }  
  59.         return autthorities ;  
  60.     }  
  61.       
  62.       
  63. }  


配置spring-security.xml 。

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

web.mvc 中配置openSessionInView

[html] view plain copy
  1. <filter>  
  2.         <filter-name>openSessionInView</filter-name>  
  3.         <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>  
  4.         <init-param>  
  5.             <param-name>singleSession</param-name>  
  6.             <param-value>true</param-value>  
  7.         </init-param>  
  8.     </filter>  
  9.       
  10.     <filter-mapping>  
  11.         <filter-name>openSessionInView</filter-name>  
  12.         <url-pattern>*.action</url-pattern>  
  13.     </filter-mapping>  
  14.       
  15.     <!-- 如果配置opensessionInView ,别忘了给login的action也加上 -->  
  16.     <filter-mapping>  
  17.         <filter-name>openSessionInView</filter-name>  
  18.         <url-pattern>/j_spring_security_check</url-pattern>  
  19.     </filter-mapping>  
  20.       
  21.       


spring-mvc.xml 中配置OpenSessionInView 

[html] view plain copy
  1. <!-- 处理在类级别上的@RequestMapping注解 -->  
  2.     <bean  
  3.         class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">  
  4.         <property name="interceptors">        <!-- 配置过滤器 -->  
  5.             <list>  
  6.                 <ref bean="openSessionInView" />  
  7.             </list>  
  8.         </property>  
  9.     </bean>  
  10.   
  11.   
  12.     <!-- 将OpenSessionInView 打开 -->  
  13.     <bean id="openSessionInView"  
  14.         class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">  
  15.         <property name="sessionFactory" ref="sessionFactory"></property>  
  16.     </bean>  


编写测试用的页面。

login.jsp

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8. <html>  
  9.   <head>  
  10.     <base href="<%=basePath%>">  
  11.       
  12.     <title>My JSP 'index.jsp' starting page</title>  
  13.     <meta http-equiv="pragma" content="no-cache">  
  14.     <meta http-equiv="cache-control" content="no-cache">  
  15.     <meta http-equiv="expires" content="0">      
  16.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  17.     <meta http-equiv="description" content="This is my page">  
  18.     <!-- 
  19.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  20.     -->  
  21.   </head>  
  22.   <body>  
  23.     <h3>用户登录</h3>  
  24.     <!-- from的action地址,以及用户名密码的name 。都是spring-security固定的。 -->  
  25.      <form action="<%=basePath %>j_spring_security_check" method="post">      
  26.     
  27.         <p>    
  28.             <label for="j_username">Username</label> <input id="j_username"    
  29.                 name="j_username" type="text" />    
  30.         </p>    
  31.     
  32.         <p>    
  33.             <label for="j_password">Password</label> <input id="j_password"    
  34.                 name="j_password" type="password" />    
  35.         </p>    
  36.           
  37.         <input type="submit" value="Login" />    
  38.     
  39.     </form>    
  40.       
  41.   </body>  
  42. </html>  

index.jsp

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
  2. <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>  
  3. <%  
  4. String path = request.getContextPath();  
  5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  6. %>  
  7.   
  8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  9. <html>  
  10.   <head>  
  11.     <base href="<%=basePath%>">  
  12.       
  13.     <title>My JSP 'index.jsp' starting page</title>  
  14.     <meta http-equiv="pragma" content="no-cache">  
  15.     <meta http-equiv="cache-control" content="no-cache">  
  16.     <meta http-equiv="expires" content="0">      
  17.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  18.     <meta http-equiv="description" content="This is my page">  
  19.     <!-- 
  20.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  21.     -->  
  22.   </head>  
  23.          
  24.   <body>         
  25.         <h3>登录成功,欢迎您:<sec:authentication property="name" /></h3>        
  26.         <a href="<%=basePath%>admin.jsp">进入管理员页面</a>  
  27.         <a href="<%=basePath%>vip.jsp">进入会员页面</a>  
  28.         <a href="<%=basePath%>auth/logout">注销</a>    
  29.   </body>  
  30. </html>  

admin.jsp
[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8. <html>  
  9.   <head>  
  10.     <base href="<%=basePath%>">  
  11.       
  12.     <title>My JSP 'index.jsp' starting page</title>  
  13.     <meta http-equiv="pragma" content="no-cache">  
  14.     <meta http-equiv="cache-control" content="no-cache">  
  15.     <meta http-equiv="expires" content="0">      
  16.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  17.     <meta http-equiv="description" content="This is my page">  
  18.     <!-- 
  19.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  20.     -->  
  21.   </head>  
  22.     
  23.   <body>    
  24.         <h3>管理员页面</h3>  
  25.   </body>  
  26. </html>  


[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8. <html>  
  9.   <head>  
  10.     <base href="<%=basePath%>">  
  11.       
  12.     <title>My JSP 'index.jsp' starting page</title>  
  13.     <meta http-equiv="pragma" content="no-cache">  
  14.     <meta http-equiv="cache-control" content="no-cache">  
  15.     <meta http-equiv="expires" content="0">      
  16.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  17.     <meta http-equiv="description" content="This is my page">  
  18.     <!-- 
  19.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  20.     -->  
  21.   </head>  
  22.     
  23.   <body>    
  24.         <h3>会员页面</h3>      
  25.   </body>  
  26. </html>  


powermiss.jsp

[html] view plain copy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7.   
  8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  9. <html>  
  10.   <head>  
  11.     <base href="<%=basePath%>">  
  12.       
  13.     <title>My JSP 'powermiss.jsp' starting page</title>  
  14.       
  15.     <meta http-equiv="pragma" content="no-cache">  
  16.     <meta http-equiv="cache-control" content="no-cache">  
  17.     <meta http-equiv="expires" content="0">      
  18.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  19.     <meta http-equiv="description" content="This is my page">  
  20.     <!-- 
  21.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  22.     -->  
  23.   
  24.   
  25.   </head>  
  26.     
  27.   <body>  
  28.       
  29.     <h1 style="color: red;">对不起,您无权访问该资源!</h1>  
  30.       
  31.   </body>  
  32. </html>  

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

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

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

spring-security3.1 + spring mvc + Hibernate 控制系统权限_第1张图片


然后就可以测试访问了。



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

AdminService.java

[java] view plain copy
  1. package com.zf.service;  
  2.   
  3. import javax.annotation.security.RolesAllowed;  
  4.   
  5. import org.springframework.security.access.prepost.PreAuthorize;  
  6.   
  7. public interface AdminService {  
  8.   
  9.     /* 拥有 Admin 权限才能的方法 ,必须定义在接口上面*/    
  10.     @PreAuthorize("hasRole('ADMIN')")  
  11.     public String test01() ;      
  12.       
  13.     @RolesAllowed({"ADMIN"})  
  14.     public String test02();  
  15.       
  16.     /* 上面的两种注解都可以 */  
  17.       
  18. }  


AdminServiceImpl.java
[java] view plain copy
  1. package com.zf.service;  
  2.   
  3. import org.springframework.stereotype.Service;  
  4.   
  5. @Service("AdminServiceImpl")  
  6. public class AdminServiceImpl implements AdminService{  
  7.          
  8.     public String test01(){      
  9.         System.out.println("方法test01被Admin用户调用");  
  10.         return "success";  
  11.     }  
  12.   
  13.     public String test02() {  
  14.         System.out.println("方法test02被Admin用户调用");  
  15.         return "success";  
  16.     }  
  17.   
  18. }  

[java] view plain copy
  1. package com.zf.control;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.springframework.context.annotation.Scope;  
  6. import org.springframework.stereotype.Controller;  
  7. import org.springframework.web.bind.annotation.RequestMapping;  
  8. import org.springframework.web.servlet.ModelAndView;  
  9.   
  10. import com.zf.service.AdminService;  
  11.   
  12. @Controller  
  13. @RequestMapping("/admin/")  
  14. @Scope("request")  
  15. public class AdminController {  
  16.       
  17.     @Resource(name = "AdminServiceImpl")  
  18.     private AdminService adminService;  
  19.       
  20.     @RequestMapping(value = "test01")  
  21.     public ModelAndView test01(){  
  22.         ModelAndView mav = new ModelAndView("admin");    
  23.         System.out.println(adminService.test01());  
  24.         return mav ;  
  25.     }  
  26.       
  27.       
  28.     @RequestMapping(value = "test02")  
  29.     public ModelAndView test02(){  
  30.         ModelAndView mav = new ModelAndView("admin");    
  31.         System.out.println(adminService.test01());  
  32.         return mav ;  
  33.     }  
  34.       
  35.       
  36. }  

向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标签内配置

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


配置登录验证码实例:

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

[java] view plain copy
  1. package com.zf.myfilter;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpServletResponse;  
  5.   
  6. import org.springframework.security.core.Authentication;  
  7. import org.springframework.security.core.AuthenticationException;  
  8. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;  
  9.   
  10. /** 
  11.  * 扩展UsernamePasswordAuthenticationFilter加上验证码的功能 
  12.  *    
  13.  * @author Administrator 
  14.  * 
  15.  */  
  16. public class VolidateAuthCodeUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{  
  17.   
  18.     @Override  
  19.     public Authentication attemptAuthentication(HttpServletRequest request,  
  20.             HttpServletResponse response) throws AuthenticationException {  
  21.         System.out.println("进入了VolidateAuthCodeUsernamePasswordAuthenticationFilter" + request.getParameter("j_username"));  
  22.         //这里可以进行验证验证码的操作  
  23.           
  24.         return super.attemptAuthentication(request, response);  
  25.     }  
  26.   
  27. }  

需要配置一个LoginUrlAuthenticationEntryPoint bean

[html] view plain copy
  1. <bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">  
  2.     <property name="loginFormUrl" value="/login.jsp"></property>  
  3. </bean>  

配置过滤器bean

[html] view plain copy
  1. <!-- 验证码过滤器 -->  
  2. <bean id="validateCodeAuthenticationFilter"  
  3.     class="com.zf.myfilter.VolidateAuthCodeUsernamePasswordAuthenticationFilter">  
  4.     <property name="authenticationSuccessHandler"  
  5.         ref="loginLogAuthenticationSuccessHandler"></property>  
  6.     <property name="authenticationFailureHandler"  
  7.         ref="simpleUrlAuthenticationFailureHandler"></property>  
  8.     <property name="authenticationManager" ref="authenticationManager"></property>  
  9. </bean>  
  10.   
  11. <!-- 登录成功 -->  
  12. <bean id="loginLogAuthenticationSuccessHandler"  
  13.     class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">  
  14.     <property name="defaultTargetUrl" value="/index.jsp"></property>  
  15. </bean>  
  16.   
  17. <!-- 登录失败 -->  
  18. <bean id="simpleUrlAuthenticationFailureHandler"  
  19.     class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">  
  20.     <property name="defaultFailureUrl" value="/index.jsp?error=true"></property>  
  21. </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 配置如下:

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  6.             http://www.springframework.org/schema/security   
  7.             http://www.springframework.org/schema/security/spring-security-3.1.xsd">  
  8.   
  9.     <!-- 启用注解方式对方法的权限控制 -->  
  10.     <security:global-method-security  
  11.         pre-post-annotations="enabled" secured-annotations="enabled"  
  12.         jsr250-annotations="enabled" proxy-target-class="true">  
  13.         <security:protect-pointcut access="VIP"  
  14.             expression="execution(* com.zf.service.VipService.*(..))" />  
  15.     </security:global-method-security>  
  16.   
  17.     <!--use-expressions="true" 的意思是开启表达式 access-denied-page的意思是,当验证权限失败后会跳转到的页面 -->  
  18.     <security:http use-expressions="true" access-denied-page="/powermiss.jsp" entry-point-ref="authenticationProcessingFilterEntryPoint">  
  19.         <!-- 对登录页面,所有的用户都可以访问 -->  
  20.         <security:intercept-url pattern="/login.jsp*"  
  21.             access="permitAll" />  
  22.         <security:intercept-url pattern="/vip.jsp*"  
  23.             access="hasRole('VIP')" />  
  24.         <security:intercept-url pattern="/admin.jsp*"  
  25.             access="hasRole('ADMIN')" />  
  26.         <!-- 对所有的资源,都必须要有COMM权限 才可以访问 -->    
  27.         <security:intercept-url pattern="/*"  
  28.             access="hasRole('COMM')" />  
  29.               
  30.         <!-- 使用自己的过滤器 -->  
  31.         <!-- 下面的配置表示将自己的过滤器放在FORM_LOGIN_FILTER过滤链的最前面(可以这样来验证登录验证码) -->  
  32.         <security:custom-filter  
  33.             ref="validateCodeAuthenticationFilter"  position="FORM_LOGIN_FILTER"  
  34.              />  
  35.               
  36.         <!-- 配置登录页面为login.jsp ,登录成功默认跳转到index.jsp,登录失败返回login.jsp并携带参数error=true -->  
  37. <!--         <security:form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true" />  -->  
  38.           
  39.         <!-- 退出配置 -->  
  40.         <security:logout invalidate-session="true"  
  41.             logout-success-url="/login.jsp" logout-url="/auth/logout" />  
  42.   
  43.     </security:http>  
  44.       
  45.       
  46.     <bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">  
  47.         <property name="loginFormUrl" value="/login.jsp"></property>  
  48.     </bean>  
  49.   
  50.     <!-- 验证码过滤器 -->  
  51.     <bean id="validateCodeAuthenticationFilter"  
  52.         class="com.zf.myfilter.VolidateAuthCodeUsernamePasswordAuthenticationFilter">  
  53.         <property name="authenticationSuccessHandler"  
  54.             ref="loginLogAuthenticationSuccessHandler"></property>  
  55.         <property name="authenticationFailureHandler"  
  56.             ref="simpleUrlAuthenticationFailureHandler"></property>  
  57.         <property name="authenticationManager" ref="authenticationManager"></property>  
  58.     </bean>  
  59.   
  60.     <!-- 登录成功 -->  
  61.     <bean id="loginLogAuthenticationSuccessHandler"  
  62.         class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">  
  63.         <property name="defaultTargetUrl" value="/index.jsp"></property>  
  64.     </bean>  
  65.   
  66.     <!-- 登录失败 -->  
  67.     <bean id="simpleUrlAuthenticationFailureHandler"  
  68.         class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">  
  69.         <property name="defaultFailureUrl" value="/index.jsp?error=true"></property>  
  70.     </bean>  
  71.   
  72.   
  73.     <!-- 配置一个认证管理器 -->  
  74.     <security:authentication-manager alias="authenticationManager">  
  75.         <!-- 使用自定义的UserDetailService -->  
  76.         <security:authentication-provider  
  77.             user-service-ref="ETUserDetailService">  
  78.             <!-- 下面的内容就可注释掉了 -->  
  79.             <!-- <security:user-service> -->  
  80.             <!-- 这样的配置表示向系统中添加了一个用户 用户名和密码都为admin ,并且该用户拥有ROLE_USER角色(角色可以用逗号隔开) -->  
  81.             <!-- <security:user name="admin" password="admin" authorities="ROLE_USER"/> -->  
  82.             <!-- </security:user-service> -->  
  83.         </security:authentication-provider>  
  84.     </security:authentication-manager>  
  85.   
  86.   
  87. </beans>  




SPEL 表达式 

[java] view plain copy
  1. //拥有DISUSER_PUBLISH_ROOM一个权限就可以访问  
  2. /   @PreAuthorize("hasRole('DISUSER_PUBLISH_ROOM')")  
  3.   
  4. //拥有DISUSER_PUBLISH_ROOM、DISUSER_MODIFY_ROOM中任意一个权限即可访问  
  5. @PreAuthorize("hasAnyRole('DISUSER_PUBLISH_ROOM','DISUSER_ADMIN')")   
  6. // or  
  7. /   @PreAuthorize("hasRole('DISUSER_PUBLISH_ROOM') or hasRole('DISUSER_MODIFY_ROOM')")  
  8.   
  9. //必须同时拥有DISUSER_PUBLISH_ROOM、DISUSER_MODIFY_ROOM两个权限才可以访问  
  10.    //@PreAuthorize("hasRole('DISUSER_PUBLISH_ROOM') and hasRole('DISUSER_MODIFY_ROOM')")  


原文地址:http://blog.csdn.net/is_zhoufeng/article/details/8495310


你可能感兴趣的:(java,spring,spring,源码,springMVC,Security)