Spring Security运用实例(一):用户登录
Spring Security应用实例(一):用户登录经过Spring Security官方文档及相关资料的学习,自己做了一个简单的
Spring Security应用实例(一):用户登录
经过Spring Security官方文档及相关资料的学习,自己做了一个简单的用户登录模块,现在将自己写的代码整理处理,以供大家参考或交流,如有不对,请指正错误。
1、库表建立
???? 1)用户表
Sql代码??
- DROP?TABLE?IF?EXISTS?`users`;??
- CREATE?TABLE?`users`?(??
- ??`id`?int(10)?NOT?NULL?auto_increment,??
- ??`login_name`?varchar(20)?default?NULL,??
- ??`password`?varchar(20)?default?NULL,??
- ??`name`?varchar(20)?default?NULL,??
- ??`email`?varchar(30)?default?NULL,??
- ??PRIMARY?KEY??(`id`)??
- )?ENGINE=InnoDB?DEFAULT?CHARSET=utf8;??
???? 2)角色表
Sql代码??
- DROP?TABLE?IF?EXISTS?`roles`;??
- CREATE?TABLE?`roles`?(??
- ??`id`?int(10)?NOT?NULL?auto_increment,??
- ??`name`?varchar(20)?default?NULL,??
- ??PRIMARY?KEY??(`id`)??
- )?ENGINE=InnoDB?DEFAULT?CHARSET=utf8;??
???? 3)权限表
Sql代码??
- DROP?TABLE?IF?EXISTS?`authorities`;??
- CREATE?TABLE?`authorities`?(??
- ??`id`?int(10)?NOT?NULL?auto_increment,??
- ??`name`?varchar(20)?default?NULL,??
- ??`display_name`?varchar(20)?default?NULL,??
- ??PRIMARY?KEY??(`id`)??
- )?ENGINE=InnoDB?DEFAULT?CHARSET=utf8;??
???? 4)用户-角色表
Sql代码??
- DROP?TABLE?IF?EXISTS?`users_roles`;??
- CREATE?TABLE?`users_roles`?(??
- ??`user_id`?int(10)?NOT?NULL,??
- ??`role_id`?int(10)?NOT?NULL,??
- ??PRIMARY?KEY??(`user_id`,`role_id`),??
- ??KEY?`FK_R_2`?(`role_id`),??
- ??CONSTRAINT?`FK_R_1`?FOREIGN?KEY?(`user_id`)?REFERENCES?`users`?(`id`),??
- ??CONSTRAINT?`FK_R_2`?FOREIGN?KEY?(`role_id`)?REFERENCES?`roles`?(`id`)??
?
??? 5)角色-权限表
Sql代码??
- DROP?TABLE?IF?EXISTS?`roles_authorities`;??
- CREATE?TABLE?`roles_authorities`?(??
- ??`role_id`?int(10)?NOT?NULL,??
- ??`authority_id`?int(10)?NOT?NULL,??
- ??PRIMARY?KEY??(`role_id`,`authority_id`),??
- ??KEY?`FK_R_4`?(`authority_id`),??
- ??CONSTRAINT?`FK_R_3`?FOREIGN?KEY?(`role_id`)?REFERENCES?`roles`?(`id`),??
- ??CONSTRAINT?`FK_R_4`?FOREIGN?KEY?(`authority_id`)?REFERENCES?`authorities`?(`id`)??
- )?ENGINE=InnoDB?DEFAULT?CHARSET=utf8;??
?
2、建立Pojo类
???? 1)用户
Java代码??
- package?cn.com.sunjiesh.springmvcdemo.entity;??
- ??
- import?javax.persistence.GeneratedValue;??
- import?javax.persistence.GenerationType;??
- import?javax.persistence.Id;??
- import?javax.persistence.MappedSuperclass;??
- ??
- /**?
- ?*?统一定义id的entity基类.?
- ?*??
- ?*?@author?calvin?
- ?*/??
- @MappedSuperclass??
- public?class?IdEntity?{??
- ??
- ????private?Long?id;??
- ??
- ????@Id??
- ????@GeneratedValue(strategy?=?GenerationType.IDENTITY)??
- ????public?Long?getId()?{??
- ????????return?id;??
- ????}??
- ??
- ????public?void?setId(Long?id)?{??
- ????????this.id?=?id;??
- ????}??
- }??
?
Java代码??
- package?cn.com.sunjiesh.springmvcdemo.entity.user;??
- ??
- import?java.util.LinkedHashSet;??
- import?java.util.List;??
- import?java.util.Set;??
- ??
- import?javax.persistence.CascadeType;??
- import?javax.persistence.Column;??
- import?javax.persistence.Entity;??
- import?javax.persistence.FetchType;??
- import?javax.persistence.JoinColumn;??
- import?javax.persistence.JoinTable;??
- import?javax.persistence.ManyToMany;??
- import?javax.persistence.OrderBy;??
- import?javax.persistence.Table;??
- import?javax.persistence.Transient;??
- ??
- import?org.apache.commons.lang.builder.ToStringBuilder;??
- import?org.hibernate.annotations.Cache;??
- import?org.hibernate.annotations.CacheConcurrencyStrategy;??
- import?org.hibernate.annotations.Fetch;??
- import?org.hibernate.annotations.FetchMode;??
- import?org.springside.modules.utils.CollectionUtils;??
- ??
- import?cn.com.sunjiesh.springmvcdemo.entity.IdEntity;??
- ??
- /**?
- ?*?用户.?
- ?*??
- ?*?注意@Cache(Entity与集合的缓存),@ManyToMany/@JoinTable(多对多关系),@OrderBy/LinkedHashSet(集合排序),@Transient(非持久化属性)的应用.?
- ?*??
- ?*?@author?calvin?
- ?*/??
- @Entity??
- @Table(name?=?"USERS")??
- @Cache(usage?=?CacheConcurrencyStrategy.READ_WRITE)??
- public?class?User?extends?IdEntity?{??
- ??
- ????private?String?loginName;??
- ??
- ????private?String?password;??
- ??
- ????private?String?name;??
- ??
- ????private?String?email;??
- ??
- ????private?Set<Role>?roles?=?new?LinkedHashSet<Role>();??
- ??
- ????@Column(name="login_name")??
- ????public?String?getLoginName()?{??
- ????????return?loginName;??
- ????}??
- ??
- ????public?void?setLoginName(String?loginName)?{??
- ????????this.loginName?=?loginName;??
- ????}??
- ??
- ????@Column(name="password")??
- ????public?String?getPassword()?{??
- ????????return?password;??
- ????}??
- ??
- ????public?void?setPassword(String?password)?{??
- ????????this.password?=?password;??
- ????}??
- ??
- ????@Column(name="name")??
- ????public?String?getName()?{??
- ????????return?name;??
- ????}??
- ??
- ????public?void?setName(String?name)?{??
- ????????this.name?=?name;??
- ????}??
- ??
- ????@Column(name="email")??
- ????public?String?getEmail()?{??
- ????????return?email;??
- ????}??
- ??
- ????public?void?setEmail(String?email)?{??
- ????????this.email?=?email;??
- ????}??
- ??
- ????@ManyToMany(cascade?=?{?CascadeType.PERSIST,?CascadeType.MERGE?},fetch=FetchType.EAGER)??
- ????@JoinTable(name?=?"USERS_ROLES",?joinColumns?=?{?@JoinColumn(name?=?"USER_ID")?},?inverseJoinColumns?=?{?@JoinColumn(name?=?"ROLE_ID")?})??
- ????@OrderBy("id")??
- ????@Cache(usage?=?CacheConcurrencyStrategy.READ_WRITE)??
- ????public?Set<Role>?getRoles()?{??
- ????????return?roles;??
- ????}??
- ??
- ????public?void?setRoles(Set<Role>?roles)?{??
- ????????this.roles?=?roles;??
- ????}??
- ??
- ????@Transient??
- ????public?String?getRoleNames()?throws?Exception?{??
- ????????return?CollectionUtils.fetchPropertyToString(roles,?"name",?",?");??
- ????}??
- ??
- ????@SuppressWarnings("unchecked")??
- ????@Transient??
- ????public?List<Long>?getRoleIds()?throws?Exception?{??
- ????????return?CollectionUtils.fetchPropertyToList(roles,?"id");??
- ????}??
- ??
- ????@Override??
- ????public?String?toString()?{??
- ????????return?ToStringBuilder.reflectionToString(this);??
- ????}??
- }??
?
???? 2)角色
Java代码??
- package?cn.com.sunjiesh.springmvcdemo.entity.user;??
- ??
- import?java.util.LinkedHashSet;??
- import?java.util.List;??
- import?java.util.Set;??
- ??
- import?javax.persistence.CascadeType;??
- import?javax.persistence.Entity;??
- import?javax.persistence.FetchType;??
- import?javax.persistence.JoinColumn;??
- import?javax.persistence.JoinTable;??
- import?javax.persistence.ManyToMany;??
- import?javax.persistence.OrderBy;??
- import?javax.persistence.Table;??
- import?javax.persistence.Transient;??
- ??
- import?org.apache.commons.lang.builder.ToStringBuilder;??
- import?org.hibernate.annotations.Cache;??
- import?org.hibernate.annotations.CacheConcurrencyStrategy;??
- import?org.springside.modules.utils.CollectionUtils;??
- ??
- import?cn.com.sunjiesh.springmvcdemo.entity.IdEntity;??
- ??
- /**?
- ?*?角色.?
- ?*??
- ?*?注意@Cache(Entity与集合的缓存),@ManyToMany/@JoinTable(多对多关系),@OrderBy/LinkedHashSet(集合排序),@Transient(非持久化属性)的应用.?
- ?*??
- ?*?@author?calvin?
- ?*/??
- @Entity??
- @Table(name?=?"ROLES")??
- @Cache(usage?=?CacheConcurrencyStrategy.READ_WRITE)??
- public?class?Role?extends?IdEntity?{??
- ??
- ????private?String?name;??
- ??
- ????private?Set<Authority>?auths?=?new?LinkedHashSet<Authority>();??
- ??
- ????public?String?getName()?{??
- ????????return?name;??
- ????}??
- ??
- ????public?void?setName(String?name)?{??
- ????????this.name?=?name;??
- ????}??
- ??
- ????@ManyToMany(cascade?=?{?CascadeType.PERSIST,?CascadeType.MERGE?},fetch=FetchType.EAGER)??
- ????@JoinTable(name?=?"ROLES_AUTHORITIES",?joinColumns?=?{?@JoinColumn(name?=?"ROLE_ID")?},?inverseJoinColumns?=?{?@JoinColumn(name?=?"AUTHORITY_ID")?})??
- ????@OrderBy("id")??
- ????@Cache(usage?=?CacheConcurrencyStrategy.READ_WRITE)??
- ????public?Set<Authority>?getAuths()?{??
- ????????return?auths;??
- ????}??
- ??
- ????public?void?setAuths(Set<Authority>?auths)?{??
- ????????this.auths?=?auths;??
- ????}??
- ??
- ????@Transient??
- ????public?String?getAuthNames()?throws?Exception?{??
- ????????return?CollectionUtils.fetchPropertyToString(auths,?"displayName",?",?");??
- ????}??
- ??
- ????@SuppressWarnings("unchecked")??
- ????@Transient??
- ????public?List<Long>?getAuthIds()?throws?Exception?{??
- ????????return?CollectionUtils.fetchPropertyToList(auths,?"id");??
- ????}??
- ??
- ????@Override??
- ????public?String?toString()?{??
- ????????return?ToStringBuilder.reflectionToString(this);??
- ????}??
- }??
?
???? 3)权限
Java代码??
- package?cn.com.sunjiesh.springmvcdemo.entity.user;??
- ??
- import?javax.persistence.Column;??
- import?javax.persistence.Entity;??
- import?javax.persistence.Table;??
- ??
- import?org.apache.commons.lang.builder.ToStringBuilder;??
- import?org.hibernate.annotations.Cache;??
- import?org.hibernate.annotations.CacheConcurrencyStrategy;??
- ??
- import?cn.com.sunjiesh.springmvcdemo.entity.IdEntity;??
- ??
- /**?
- ?*?权限.?
- ?*??
- ?*?@Cache使用READ_ONLY策略.?
- ?*??
- ?*?@author?calvin?
- ?*/??
- @Entity??
- @Table(name?=?"AUTHORITIES")??
- @Cache(usage?=?CacheConcurrencyStrategy.READ_ONLY)??
- public?class?Authority?extends?IdEntity?{??
- ??
- ????private?String?name;??
- ??
- ????private?String?displayName;??
- ??
- ????public?String?getName()?{??
- ????????return?name;??
- ????}??
- ??
- ????public?void?setName(String?name)?{??
- ????????this.name?=?name;??
- ????}??
- ??
- ????@Column(name="display_name")??
- ????public?String?getDisplayName()?{??
- ????????return?displayName;??
- ????}??
- ??
- ????public?void?setDisplayName(String?displayName)?{??
- ????????this.displayName?=?displayName;??
- ????}??
- ??
- ????@Override??
- ????public?String?toString()?{??
- ????????return?ToStringBuilder.reflectionToString(this);??
- ????}??
- }??
?
???? 注意:@ManyToMany中的fetch=FetchType.EAGER。如果fetch=FetchType.LAZY会报异常。
3、建立DAO类
??? 1)接口
?
Java代码??
- package?cn.com.sunjiesh.springmvcdemo.dao.iface;??
- ??
- import?cn.com.sunjiesh.springmvcdemo.entity.user.User;??
- ??
- ??
- ??
- /**?
- ?*??
- ?*?@author?sunjie?
- ?*?@since?2009-03-29?
- ?*??
- ?*/??
- public?interface?IUserDAO?extends?IBaseHibernateDAO<User>?{??
- ??
- ????public?User?getUserByUserName(String?username);??
- ??
- }??
?
??? 2)实现类
Java代码??
- package?cn.com.sunjiesh.springmvcdemo.dao.impl;??
- ??
- import?org.apache.log4j.Logger;??
- import?org.hibernate.Query;??
- ??
- ??
- import?cn.com.sunjiesh.springmvcdemo.dao.iface.IUserDAO;??
- import?cn.com.sunjiesh.springmvcdemo.entity.user.User;??
- ??
- public?class?UserDAOImpl?extends?BaseHibernateDAOImpl<User>?implements?IUserDAO?{??
- ??
- ????private?static?Logger?LOG?=?Logger.getLogger(UserDAOImpl.class);??
- ??
- ????public?User?getUserByUserName(String?username)?{??
- ????????String?hql?=?"from?User?where?loginName?=??";??
- ????????Query?query?=?getSession().createQuery(hql);??
- ????????query.setParameter(0,?username);??
- ????????User?user?=?(User)?query.list().get(0);??
- ????????return?user;??
- ????}??
- ??
- }??
?
4、Spring Security相关代码
Java代码??
- package?cn.com.sunjiesh.springmvcdemo.service.security;??
- ??
- import?java.util.ArrayList;??
- import?java.util.List;??
- ??
- import?org.apache.log4j.Logger;??
- import?org.springframework.dao.DataAccessException;??
- import?org.springframework.security.GrantedAuthority;??
- import?org.springframework.security.GrantedAuthorityImpl;??
- ??
- import?org.springframework.security.userdetails.UserDetails;??
- import?org.springframework.security.userdetails.UserDetailsService;??
- import?org.springframework.security.userdetails.UsernameNotFoundException;??
- ??
- import?cn.com.sunjiesh.springmvcdemo.dao.iface.IUserDAO;??
- import?cn.com.sunjiesh.springmvcdemo.entity.user.Authority;??
- import?cn.com.sunjiesh.springmvcdemo.entity.user.Role;??
- import?cn.com.sunjiesh.springmvcdemo.entity.user.User;??
- ??
- ??
- ??
- /**?
- ?*?实现SpringSecurity的UserDetailsService接口,获取用户Detail信息.?
- ?*?@author?calvin?
- ?*/??
- public?class?UserDetailServiceImpl?implements?UserDetailsService{??
- ??
- ????private?static?Logger?LOG=Logger.getLogger(UserDetailServiceImpl.class);??
- ??????
- ????private?IUserDAO?userDao;??
- ??????
- ????public?UserDetails?loadUserByUsername(String?username)??
- ????????????throws?UsernameNotFoundException,?DataAccessException?{??
- ????????if(username==null){??
- ????????????LOG.error("username?is?null");??
- ????????}??
- ????????if(userDao==null){??
- ????????????LOG.error("userDao?is?null");??
- ????????}??
- ????????User?user=userDao.getUserByUserName(username);??
- ????????//TOTO?判断用户存在,如果不存在,则抛出异常。??
- ????????if(user==null){??
- ????????????LOG.error(username+"?is?not?exist",?new?UsernameNotFoundException(username+"?is?not?exist"));??
- ????????}??
- ??????????
- ????????List<GrantedAuthority>?authsList?=?new?ArrayList<GrantedAuthority>();??
- ??????????
- ????????System.out.println("user.getRoles().size()="+user.getRoles().size());??
- ????????for?(Role?role?:?user.getRoles())?{??
- ????????????for?(Authority?authority?:?role.getAuths())?{??
- ????????????????authsList.add(new?GrantedAuthorityImpl(authority.getName()));??
- ????????????}??
- ????????}??
- ??????????
- ????????//TODO ??
- ????????org.springframework.security.userdetails.User?userdetail?=?new?org.springframework.security.userdetails.User(??
- ????????????????user.getLoginName(),?user.getPassword(),?true,?true,?true,?true,?authsList??
- ????????????????????????.toArray(new?GrantedAuthority[authsList.size()]));??
- ??
- ????????return?userdetail;??
- ????}??
- ??
- ????public?void?setUserDao(IUserDAO?userDao)?{??
- ????????this.userDao?=?userDao;??
- ????}??
- }??
?
5、配置文件
??? 1)web.xml
Xml代码??
- <?xml?version="1.0"?encoding="UTF-8"?>??
- <web-app?id="WebApp_ID"?version="2.4"??
- ????xmlns="http://java.sun.com/xml/ns/j2ee"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
- ????xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee?http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">??
- ????<display-name>?SpringMVCDemo</display-name>??
- ????<context-param>??
- ????????<param-name>contextConfigLocation</param-name>??
- ????????<param-value>classpath:/cn/com/sunjiesh/springmvcdemo/spring/spring-*.xml,/WEB-INF/springmvcdemo-servlet.xml</param-value>??
- ????</context-param>??
- ????<listener>??
- ????????<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>??
- ????</listener>??
- ????<!--??
- ????????Spring?Security可以限制一个主体并行认证到同一系统的次数。??
- ????????很多ISV利用这点来加强授权公里,网管也喜欢这个功能,因为它可以防止人们共享登录名。??
- ????????你可以,比如,禁止用户"Batman"从两个不同的会话登录到web应用里。??
- ????-->??
- ????<listener>??
- ????????<listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>??
- ????</listener>??
- ??????
- ??????
- ????<!--Character?Encoding?Convert-->??
- ????<filter>??
- ????????<filter-name>encodingFilter</filter-name>??
- ????????<filter-class>?org.springframework.web.filter.CharacterEncodingFilter???
- ????????</filter-class>??
- ????????<init-param>??
- ????????????<param-name>encoding</param-name>??
- ????????????<param-value>gb2312</param-value>??
- ????????</init-param>??
- ????</filter>??
- ????<filter-mapping>??
- ????????<filter-name>encodingFilter</filter-name>??
- ????????<url-pattern>*.do</url-pattern>??
- ????</filter-mapping>??
- ????<!--?Spring?Security?Filter-->??
- ????<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>??
- ??????
- ????<!--?Use?DWR?-->??
- ????<servlet>??
- ????????<servlet-name>dwr-invoker</servlet-name>??
- ????????<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>??
- ????</servlet>??
- ????<servlet-mapping>??
- ????????<servlet-name>dwr-invoker</servlet-name>??
- ????????<url-pattern>/dwr/*</url-pattern>??
- ????</servlet-mapping>??
- ????<!--?Spring?MVC?Dispatcher?-->??
- ????<servlet>??
- ????????<servlet-name>springmvcdemo</servlet-name>??
- ????????<servlet-class>?org.springframework.web.servlet.DispatcherServlet???
- ????????</servlet-class>??
- ????????<init-param>??
- ????????????<param-name>contextConfigLocation</param-name>??
- ????????????<param-value>WEB-INF/springmvcdemo-servlet.xml</param-value>??
- ????????</init-param>??
- ????????<load-on-startup>1</load-on-startup>??
- ????</servlet>??
- ????<servlet-mapping>??
- ????????<servlet-name>springmvcdemo</servlet-name>??
- ????????<url-pattern>*.do</url-pattern>??
- ????</servlet-mapping>??
- ??????
- ????<!--?JSTL?Configuration?-->??
- ????<jsp-config>??
- ????????<taglib>??
- ????????????<taglib-uri>http://java.sun.com/jstl/fmt</taglib-uri>??
- ????????????<taglib-location>/WEB-INF/tlds/fmt.tld</taglib-location>??
- ????????</taglib>??
- ????????<taglib>??
- ????????????<taglib-uri>http://java.sun.com/jstl/fmt-rt</taglib-uri>??
- ????????????<taglib-location>/WEB-INF/tlds/fmt-rt.tld</taglib-location>??
- ????????</taglib>??
- ????????<taglib>??
- ????????????<taglib-uri>http://java.sun.com/jstl/core</taglib-uri>??
- ????????????<taglib-location>/WEB-INF/tlds/c.tld</taglib-location>??
- ????????</taglib>??
- ????????<taglib>??
- ????????????<taglib-uri>http://java.sun.com/jstl/core-rt</taglib-uri>??
- ????????????<taglib-location>/WEB-INF/tlds/c-rt.tld</taglib-location>??
- ????????</taglib>??
- ????????<taglib>??
- ????????????<taglib-uri>http://java.sun.com/jstl/sql</taglib-uri>??
- ????????????<taglib-location>/WEB-INF/tlds/sql.tld</taglib-location>??
- ????????</taglib>??
- ????????<taglib>??
- ????????????<taglib-uri>http://java.sun.com/jstl/sql-rt</taglib-uri>??
- ????????????<taglib-location>/WEB-INF/tlds/sql-rt.tld</taglib-location>??
- ????????</taglib>??
- ????????<taglib>??
- ????????????<taglib-uri>http://java.sun.com/jstl/x</taglib-uri>??
- ????????????<taglib-location>/WEB-INF/tlds/x.tld</taglib-location>??
- ????????</taglib>??
- ????????<taglib>??
- ????????????<taglib-uri>http://java.sun.com/jstl/x-rt</taglib-uri>??
- ????????????<taglib-location>/WEB-INF/tlds/x-rt.tld</taglib-location>??
- ????????</taglib>??
- ????</jsp-config>??
- ????<welcome-file-list>??
- ????????<welcome-file>index.html</welcome-file>??
- ????????<welcome-file>index.htm</welcome-file>??
- ????????<welcome-file>index.jsp</welcome-file>??
- ????????<welcome-file>default.html</welcome-file>??
- ????????<welcome-file>default.htm</welcome-file>??
- ????????<welcome-file>default.jsp</welcome-file>??
- ????</welcome-file-list>??
- </web-app>??
?
?
??? 2)spring-base.xml
Xml代码??
- <?xml?version="1.0"?encoding="UTF-8"?>??
- <!DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN//EN"?"http://www.springframework.org/dtd/spring-beans.dtd">??
- <beans>??
- ????<bean?id="propertyConfigurer"??
- ????????class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">??
- ????????<property?name="locations">??
- ????????????<list>??
- ????????????????<value>classpath:/cn/com/sunjiesh/springmvcdemo/spring/jdbc.properties</value>??
- ????????????</list>??
- ????????</property>??
- ????</bean>??
- ????<bean?id="dataSource"?class="org.apache.commons.dbcp.BasicDataSource"??
- ????????destroy-method="close">??
- ????????<property?name="driverClassName"?value="${jdbc.driverClassName}"?/>??
- ????????<property?name="url"?value="${jdbc.url}"?/>??
- ????????<property?name="username"?value="${jdbc.username}"?/>??
- ????????<property?name="password"?value="${jdbc.password}"?/>??
- ????</bean>??
- ????<bean?id="sessionFactory"??
- ????????class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">??
- ????????<property?name="dataSource"?ref="dataSource"?/>??
- ????????<!--?Hibernate?Annotation?Entity?-->??
- ????????<property?name="annotatedClasses">??
- ????????????<list>??
- ????????????????<value>cn.com.sunjiesh.springmvcdemo.entity.user.Authority</value>??
- ????????????????<value>cn.com.sunjiesh.springmvcdemo.entity.user.Role</value>??
- ????????????????<value>cn.com.sunjiesh.springmvcdemo.entity.user.User</value>??
- ????????????</list>??
- ????????</property>??
- ????????<property?name="hibernateProperties">??
- ????????????<props>??
- ????????????????<prop?key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>??
- ????????????????<prop?key="hibernate.show_sql">true</prop>??
- ????????????????<prop?key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>??
- ????????????????<prop?key="hibernate.cache.use_second_level_cache">false</prop>??
- ????????????????<prop?key="hibernate.cache.use_query_cache">false</prop>??
- ????????????</props>??
- ????????</property>??
- ????</bean>??
- ????<bean?id="txManager"??
- ????????class="org.springframework.orm.hibernate3.HibernateTransactionManager">??
- ????????<property?name="sessionFactory"?ref="sessionFactory"?/>??
- ????</bean>??
- ????<bean?id="baseTxService"??
- ????????class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"??
- ????????abstract="true">??
- ????????<property?name="transactionManager"?ref="txManager"?/>??
- ????????<property?name="proxyTargetClass"?value="true"?/>??
- ????????<property?name="transactionAttributes">??
- ????????????<props>??
- ????????????????<prop?key="get*">PROPAGATION_REQUIRED,readOnly</prop>??
- ????????????????<prop?key="find*">PROPAGATION_REQUIRED,readOnly</prop>??
- ????????????????<prop?key="load*">PROPAGATION_REQUIRED,readOnly</prop>??
- ????????????????<prop?key="save*">PROPAGATION_REQUIRED</prop>??
- ????????????????<prop?key="update*">PROPAGATION_REQUIRED</prop>??
- ????????????????<prop?key="remove*">PROPAGATION_REQUIRED</prop>??
- ????????????</props>??
- ????????</property>??
- ????</bean>??
- </beans>??
?
??? 3)spring-dao.xml
Xml代码??
- <?xml?version="1.0"?encoding="UTF-8"?>??
- <!DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN//EN"?"http://www.springframework.org/dtd/spring-beans.dtd">??
- <!--???
- ????Author?By?Sun?Jie??
- ????Shared?document??
- -->??
- <beans?default-autowire="byName"?default-lazy-init="true">??
- ??????
- ????<!--?Add?By?Sun?Jie?-->??
- ????<bean?id="userDaoTarget"?class="cn.com.sunjiesh.springmvcdemo.dao.impl.UserDAOImpl">??
- ????</bean>??
- ????<!--?End?Edit?-->??
- ??????
- ????<!--?Add?By?Sun?Jie?-->??
- ????<bean?id="userDao"?parent="baseTxService">??
- ????????<property?name="target">??
- ????????????<ref?bean="userDaoTarget"/>??
- ????????</property>??
- ????</bean>??
- ????<!--?End?Edit?-->??
- </beans>??
?
??? 4)spring-security.xml
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"??
- ????xmlns:security="http://www.springframework.org/schema/security"??
- ????xsi:schemaLocation="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-2.5.xsd??
- ????????http://www.springframework.org/schema/security?http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">??
- ????<!--?
- ????????FilterChainProxy会按顺序来调用这些filter,使这些filter能享用Spring?Ioc的功能?
- ????-->??
- ????<bean?id="springSecurityFilterChain"?class="org.springframework.security.util.FilterChainProxy">??
- ????????<security:filter-chain-map?path-type="ant">??
- ????????????<security:filter-chain?pattern="/user/**"??
- ????????????????filters="httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,exceptionTranslationFilter"?/>??
- ????????</security:filter-chain-map>??
- ????</bean>??
- ????<!--??
- ????????集成过滤器(HttpSessionContextIntegrationFilter是集成过滤器的一个实现)??
- ????????每次request前HttpSessionContextIntegrationFilter从Session中获取Authentication对象,在request完后??
- ????????又把Authentication对象保存到Session中供下次request使用,此filter必须在其他Acegi?filter前使用??
- ????-->??
- ????<bean?id="httpSessionContextIntegrationFilter"??
- ????????class="org.springframework.security.context.HttpSessionContextIntegrationFilter"?/>??
- ??????
- ????<!--?
- ????????退出(Logout)过滤器?退出登录操作?
- ????-->??
- ????<bean?id="logoutFilter"?class="org.springframework.security.ui.logout.LogoutFilter">??
- ????????<!--?退出系统后系统跳转到此URL?-->??
- ????????<constructor-arg?value="/login.action"?/>??
- ????????<!--?退出系统后的操作(调用logout方法)?-->??
- ????????<constructor-arg>??
- ????????????<list>??
- ????????????????<!--?实现了LogoutHandler接口(logout方法)?-->??
- ????????????????<ref?bean="rememberMeServices"?/>??
- ????????????????<bean??
- ????????????????????class="org.springframework.security.ui.logout.SecurityContextLogoutHandler"?/>??
- ????????????</list>??
- ????????</constructor-arg>??
- ????</bean>??
- ????<!--??
- ????????处理表单认证filter:?1.authenticationManager?认证管理器?2.authenticationFailureUrl??
- ????????定义登录失败时转向的页面?3.defaultTargetUrl?定义登录成功时转向的页面?4.filterProcessesUrl??
- ????????定义登录请求的地址?5.rememberMeServices?在验证成功后添加cookie信息??
- ????-->??
- ????<bean?id="authenticationProcessingFilter"??
- ????????class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">??
- ????????<property?name="authenticationManager"?ref="authenticationManager"></property>??
- ????????<property?name="authenticationFailureUrl"?value="/user/login.jsp"></property>??
- ????????<property?name="defaultTargetUrl"?value="/user/index.jsp"></property>??
- ????????<property?name="filterProcessesUrl"?value="/user/j_spring_security_check"></property>??
- ????????<property?name="rememberMeServices"?ref="rememberMeServices"></property>??
- ????</bean>??
- ??????
- ????<!--?基本认证机制处理?-->??
- ????<bean?id="basicProcessingFilter"??
- ????????class="org.springframework.security.ui.basicauth.BasicProcessingFilter">??
- ????????<property?name="authenticationManager">??
- ????????????<ref?bean="authenticationManager"?/>??
- ????????</property>??
- ????????<property?name="authenticationEntryPoint">??
- ????????????<bean?id="authenticationEntryPoint"??
- ????????????????class="org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint">??
- ????????????????<property?name="realmName">??
- ????????????????????<value>Name?Of?Your?Realm</value>??
- ????????????????</property>??
- ????????????</bean>??
- ????????</property>??
- ????</bean>??
- ????<bean?id="securityContextHolderAwareRequestFilter"??
- ????????class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter"?/>??
- ????????<!--?
- ????????如果不存在任何授权信息时,自动添加匿名用户身份至SecurityContextHolder中?
- ????-->??
- ????<bean?id="anonymousProcessingFilter"??
- ????????class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">??
- ????????<property?name="key"?value="springsecurity"></property>??
- ????????<property?name="userAttribute"?value="anonymousUser,ROLE_ANONYMOUS"></property>??
- ????</bean>??
- ????<!--??
- ????????异常处理filter(异常转换过滤器),主要是处理AccessDeniedException和AuthenticationException,??
- ????????将给每个异常找到合适的"去向"??
- ????-->??
- ????<bean?id="exceptionTranslationFilter"??
- ????????class="org.springframework.security.ui.ExceptionTranslationFilter">??
- ????????<property?name="authenticationEntryPoint"?ref="authenticationProcessingFilterEntryPoint"?/>??
- ????????<property?name="accessDeniedHandler">??
- ????????????<bean?class="org.springframework.security.ui.AccessDeniedHandlerImpl">??
- ????????????????<property?name="errorPage"?value="/accessDenied.jsp"?/>??
- ????????????</bean>??
- ????????</property>??
- ????</bean>??
- ????<!--??
- ????????使用过滤器安全拦截器保护资源??
- ????????filterSecurityInterceptor在执行转向目标url前检查objectDefinitionSource中设定的用户权限信息,??
- ????????安全强制过滤器负责拦截请求,判断请求是否安全,并且给予认证和访问决策管理器一个机会来验证用户的身份和权限?过程:??
- ????????首先,过滤器安全拦截器使用authenticationManager调用自己的provider来对用户的认证信息进行验证并获取用户已有的权限。??
- ????????然后,使用访问决策管理器来判断用户是否拥用合适的授权来访问受保护的资源。??
- ????????(objectDefinitionSource属性定义了访问URL需要的权限信息)??
- ????????最后,有投票者根据用户持有认证和访问url需要的属性,调用自己的voter来投票,决定是否允许访问。??
- ????-->??
- ????<bean?id="filterSecurityInterceptor"??
- ????????class="org.springframework.security.intercept.web.FilterSecurityInterceptor">??
- ????????<property?name="authenticationManager"?ref="authenticationManager"></property>??
- ????????<property?name="accessDecisionManager"?ref="accessDecisionManager"></property>??
- ????????<!--??
- ????????????<property?name="objectDefinitionSource"??
- ????????????ref="objectDefinitionSource"></property>??
- ????????-->??
- ????????<property?name="objectDefinitionSource">??
- ????????????<security:filter-invocation-definition-source>??
- ????????????????<security:intercept-url?pattern="/secure/super/**"??
- ????????????????????access="ROLE_WE_DONT_HAVE"?/>??
- ????????????????<security:intercept-url?pattern="/secure/**"??
- ????????????????????access="ROLE_SUPERVISOR,ROLE_TELLER"?/>??
- ????????????????<security:intercept-url?pattern="/login.action*"??
- ????????????????????access="IS_AUTHENTICATED_ANONYMOUSLY"?/>??
- ????????????????<security:intercept-url?pattern="/user/user!save.action*"??
- ????????????????????access="ROLE_MODIFY_USER"?/>??
- ????????????????<security:intercept-url?pattern="/user/user!delete.action*"??
- ????????????????????access="ROLE_MODIFY_USER"?/>??
- ????????????????<security:intercept-url?pattern="/user/user*.action*"??
- ????????????????????access="ROLE_VIEW_USER"?/>??
- ????????????????<security:intercept-url?pattern="/user/role!save.action*"??
- ????????????????????access="ROLE_MODIFY_ROLE"?/>??
- ????????????????<security:intercept-url?pattern="/user/role!delete.action*"??
- ????????????????????access="ROLE_MODIFY_ROLE"?/>??
- ????????????????<security:intercept-url?pattern="/user/role*.action*"??
- ????????????????????access="ROLE_VIEW_ROLE"?/>??
- ????????????</security:filter-invocation-definition-source>??
- ????????</property>??
- ????</bean>??
- ????<!--??
- ????????访问决策管理器??
- ????????验证用户是否有权限访问相应的资源(filterSecurityInterceptor中objectDefinitionSource属性定义的访问URL需要的属性信息)??
- ????-->??
- ????<bean?id="accessDecisionManager"?class="org.springframework.security.vote.AffirmativeBased"??
- ????????p:allowIfAllAbstainDecisions="false">??
- ????????<property?name="decisionVoters">??
- ????????????<list>??
- ????????????????<bean?class="org.springframework.security.vote.RoleVoter"?/>??
- ????????????????<bean?class="org.springframework.security.vote.AuthenticatedVoter"?/>??
- ????????????</list>??
- ????????</property>??
- ????</bean>??
- ????<bean?id="authenticationProcessingFilterEntryPoint"??
- ????????class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">??
- ????????<property?name="loginFormUrl"?value="/login.jsp"?/>??
- ????????<property?name="forceHttps"?value="false"?/>??
- ????</bean>??
- ????<!--??
- ????????认证管理器(org.springframework.security.AuthenticationManager接口)??
- ????????org.springframework.security.providers.ProviderManager是认证管理器的一个实现,??
- ????????ProviderManager通过遍历一个提供者的集合来实现身份验证,?直到某一个认证提供者能够成功地验证该用户的身份??
- ????-->??
- ????<!--??
- ????????通过Providers提供认证者列表,如果一个认证提供者失败可以尝试另外一个认证提供者,以保证获取不同来源的身份认证,如??
- ????????DaoAuthenticationProvider?从数据库中读取用户信息验证身份??
- ????????AnonymousAuthenticationProvider?匿名用户身份认证??
- ????????RememberMeAuthenticationProvider?已存cookie中的用户信息身份认证?其它的还有??
- ????????AuthByAdapterProvider?使用容器的适配器验证身份?CasAuthenticationProvider??
- ????????根据Yale中心认证服务验证身份,?用于实现单点登陆?JaasAuthenticationProvider??
- ????????从JASS登陆配置中获取用户信息验证身份?RemoteAuthenticationProvider?根据远程服务验证用户身份??
- ????????RunAsImplAuthenticationProvider?对身份已被管理器替换的用户进行验证??
- ????????X509AuthenticationProvider?从X509认证中获取用户信息验证身份??
- ????????TestingAuthenticationProvider?单元测试时使用??
- ????????每个认证者会对自己指定的证明信息进行认证,如DaoAuthenticationProvider仅对UsernamePasswordAuthenticationToken这个证明信息进行认证。??
- ????-->??
- ????<bean?id="authenticationManager"?class="org.springframework.security.providers.ProviderManager">??
- ????????<property?name="providers">??
- ????????????<list>??
- ????????????????<ref?local="daoAuthenticationProvider"?/>??
- ????????????????<ref?local="anonymousAuthenticationProvider"?/>??
- ????????????</list>??
- ????????</property>??
- ????????<!--?<property?name="sessionController"?ref="concurrentSessionController"?/>?-->??
- ????</bean>??
- ????<bean?id="daoAuthenticationProvider"??
- ????????class="org.springframework.security.providers.dao.DaoAuthenticationProvider">??
- ????????<!--??<property?name="passwordEncoder"?ref="passwordEncoder"></property>-->??
- ????????<property?name="userDetailsService"?ref="userDetailsService"></property>??
- ????</bean>??
- ????<bean?id="anonymousAuthenticationProvider"??
- ????????class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider">??
- ????????<property?name="key"?value="springsecurity"></property>??
- ????</bean>??
- ????<!--?RemeberMeServices?-->??
- ????<bean?id="rememberMeServices"??
- ????????class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices">??
- ????????<property?name="key"?value="springsecurity"></property>??
- ????????<property?name="userDetailsService"?ref="userDetailsService"></property>??
- ????</bean>??
- ????<bean?id="userDetailsService"??
- ????????class="cn.com.sunjiesh.springmvcdemo.service.security.UserDetailServiceImpl">??
- ????????<property?name="userDao"?ref="userDao"></property>??
- ????????</bean>??
- ????<bean?id="passwordEncoder"??
- ????????class="org.springframework.security.providers.encoding.Md5PasswordEncoder"?/>??
- ????<bean?id="loggerListener"??
- ????????class="org.springframework.security.event.authentication.LoggerListener"?/>??
- </beans>??
?
??? 5)springmvcdemo-servlet.xml
Xml代码??
- <?xml?version="1.0"?encoding="UTF-8"?>??
- <!--??
- ????Author?Sun?Jie?
- ?-->??
- <!DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN//EN"?"http://www.springframework.org/dtd/spring-beans.dtd">??
- <beans>??
- ??
- ????<!--?Multi-Action-->??
- ????<bean?id="methodNameResolver"??
- ????????class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">??
- ????????<property?name="paramName"?value="method"?/>??
- ????????<property?name="defaultMethodName"?value="index"?/>??
- ????</bean>??
- ????<!--?View?Resolver?-->??
- ????<bean?id="viewResolver"??
- ????????class="org.springframework.web.servlet.view.InternalResourceViewResolver">??
- ????????<property?name="viewClass"??
- ????????????value="org.springframework.web.servlet.view.JstlView"?/>??
- ????????<property?name="prefix"?value="/"?/>??
- ????</bean>??
- ????<bean?id="adminHandlerMapping"??
- ????????class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">??
- ????????<property?name="mappings">??
- ????????????<props>??
- ????????????????<!--?Add?By?Sun?Jie?-->??
- ????????????????<prop?key="/user/login.do">userLoginController</prop>??
- ????????????????<!--?Add?By?Sun?Jie?-->??
- ????????????</props>??
- ????????</property>??
- ????</bean>??
- ??????
- ????<bean?id="userLoginController"?class="cn.com.sunjiesh.springmvcdemo.web.user.LoginController"??
- ????????autowire="byName">??
- ????????<property?name="successView"?value="/user/index.jsp"?/>??
- ????????<property?name="errorView"?value=""?/>??
- ????</bean>??
- </beans>??
?
6、页面
Html代码??
- <%@?page?contentType="text/html;charset=gb2312"%>??
- <%@?taglib?prefix="c"?uri="http://java.sun.com/jsp/jstl/core"?%>??
- <%@?taglib?prefix="security"?uri="http://www.springframework.org/security/tags"?%>??
- <%@?page?import="org.springframework.security.ui.AbstractProcessingFilter"%>??
- <%@?page?import="org.springframework.security.ui.webapp.AuthenticationProcessingFilter"%>??
- <%@?page?import="org.springframework.security.AuthenticationException"%>??
- ??
- <!DOCTYPE?html?PUBLIC?"-//W3C//DTD?XHTML?1.0?Transitional//EN"?"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">??
- <html?xmlns="http://www.w3.org/1999/xhtml">??
- ????<head>??
- ????????<title>SpringMVCDemo登录页</title>??
- ????????<%@?include?file="/common/meta.jsp"%>??
- ????????<script?src="${ctx}/js/validate/jquery.validate.js"?type="text/javascript"></script>??
- ????????<script?src="${ctx}/js/validate/messages_cn.js"?type="text/javascript"></script>??
- ????????<script>??
- ????????????$(document).ready(function(){??
- ????????????????$("#loginForm").validate();??
- ?????????????});??
- ????????</script>??
- ????</head>??
- ????<body>??
- <c:set?var="ctx"?value="${pageContext.request.contextPath}"/>??
- ????????<div?id="content">??
- ????????????<%??
- ????????????????if?(session.getAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY)?!=?null)?{??
- ????????????%>??
- ????????????<span?style="color:red">?登录失败,请重试.?</span>??
- ????????????<%??
- ????????????????}??
- ????????????%>??
- ????????????<h2>SpringMVCDemo示例</h2>??
- ????????????<h3>--CRUD管理界面演示</h3>??
- ????????????<form?id="loginForm"?action="${ctx}/user/j_spring_security_check"?method="post">??
- ????????????????<table?class="inputView">??
- ????????????????????<tr>??
- ????????????????????????<td>??
- ????????????????????????????用户名:??
- ????????????????????????</td>??
- ????????????????????????<td>??
- ????????????????????????????<input?type='text'?name='j_username'??
- ????????????????????????????????<c:if?test="${not?empty?param.error}">?value='<%=session.getAttribute(AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY)%>'</c:if>?class="required"/>??
- ????????????????????????</td>??
- ????????????????????</tr>??
- ????????????????????<tr>??
- ????????????????????????<td>??
- ????????????????????????????密码:??
- ????????????????????????</td>??
- ????????????????????????<td>??
- ????????????????????????????<input?type='password'?name='j_password'?class="required"?/>??
- ????????????????????????</td>??
- ????????????????????</tr>??
- ????????????????????<tr>??
- ????????????????????????<td?colspan='2'>??
- ????????????????????????????<input?value="登录"?type="submit"?/>??
- ????????????????????????</td>??
- ????????????????????</tr>??
- ????????????????</table>??
- ????????????</form>??
- ????????</div>??
- ????</body>??
- </html>??
?备注:登录页面上的表单action与spring-security中authenticationProcessingFilter过滤器中的filterProcessesUrl相对应。用户名与输入框的name属性值分别是j_username与j_password。