第一步
下载spring-security3.1
解压后进入dist目录,里面有两个war文件,解压其中一个。
然后将里面的jar包全部复制到项目中。
第二步
配置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.xsd
http://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.xsd
http://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注解 -->
<bean
class="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.xsd
http://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();
/* 上面的两种注解都可以 */
}
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{
@Override
public 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.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- 启用注解方式对方法的权限控制 -->
<security:global-method-security
pre-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-filter
ref="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-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>
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')")
未完待续》。。