session-management spring security获得session 2.0支持吗

spring security 使用 - 从头开始 - ITeye技术网站
博客分类:
使用篇 1、建立login.jsp页面.内容如下: Html代码
&form action="&%=path %&/j_spring_security_check" method="post"&
USERNAME:&input type="text" name="j_username" value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}" /&&br/&
PASSWORD:&input type="password" name="j_password" value="" /&&br/&
&input type="checkbox" name="_spring_security_remember_me" /&两周之内不必登陆&br/&
&input type="submit"&
&form action="&%=path %&/j_spring_security_check" method="post"&
USERNAME:&input type="text" name="j_username" value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}" /&&br/&
PASSWORD:&input type="password" name="j_password" value="" /&&br/&
&input type="checkbox" name="_spring_security_remember_me" /&两周之内不必登陆&br/&
&input type="submit"&
j_spring_security_check : 为security验证中心(不知道怎么说合适.暂时这么理解吧..). j_username: 验证用户名; j_password: 验证密码; ${sessionScope['SPRING_SECURITY_LAST_USERNAME']}:使用最后一次登录用户名. _spring_security_remember_me:记住我... 2、xml配置,配置内容如下: Xml代码
&?xml version="1.0" encoding="UTF-8"?&
&beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd"&
&!-- auto-config = true 则使用from-login. 如果不使用该属性 则默认为http-basic(没有session).
access-denied-page:出错后跳转到的错误页面;
&http auto-config="true" access-denied-page="/common/403.jsp"&
&!-- intercept-url:拦截器,可以设定哪些路径需要哪些权限来访问. filters=none 不使用过滤,也可以理解为忽略 --&
&intercept-url pattern="/index.jsp" access="ROLE_USER" /&
&intercept-url pattern="/login.jsp" filters="none" /&
&intercept-url pattern="/common/**" filters="none" /&
&intercept-url pattern="/script/**" filters="none" /&
&intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" /&
&intercept-url pattern="/user.jsp" access="ROLE_USER" /&
&!-- session-management是针对session的管理. 这里可以不配置. 如有需求可以配置. --&
&!-- id登陆唯一. 后登陆的账号会挤掉第一次登陆的账号
error-if-maximum-exceeded="true" 禁止2次登陆;
session-fixation-protection="none" 防止伪造sessionid攻击. 用户登录成功后会销毁用户当前的session.
创建新的session,并把用户信息复制到新session中.
&session-management session-fixation-protection="none"&
&concurrency-control/&
&/session-management&
&!-- login-page:默认指定的登录页面. authentication-failure-url:出错后跳转页面. default-target-url:成功登陆后跳转页面 --&
&form-login login-page="/login.jsp"
authentication-failure-url="/common/403.jsp"
default-target-url="/admin.jsp" /&
&!-- logout-success-url:成功注销后跳转到的页面; --&
&logout logout-success-url="/login.jsp"/&
&http-basic /&
浏览 10604
浏览: 73528 次
来自: 成都
写的很好啊,赞!
Handler初始化的应该注册read,否则select就会阻 ...
运行了不正确呢那些年掉过SpringSecurity的坑。
最近在研究SpringBoot集成SpringSecurity权限框架的Demo,关于怎么集成,网上一大片的文章,我就不废话多说了,自行百度解决。
我使用的是注解配置,类继承WebSecurityConfigurerAdapter适配器,重写configure(HttpSecurity http)方法配置参数等。
然后是继承UserDetails抽象接口实现自定义的User对象,而SpringSecurity管理Session也是通过管理User对象实现的。
然后到了配置Session的并发步骤了,不管是通过HttpSecurity配置还是XML方式配置其目的都是一样的,以下是HttpSecurity配置。
http.sessionManagement()//Session管理器
.maximumSessions(1)
.sessionRegistry(sessionRegistry)
.expiredUrl(&/Member/Login.html&);
好了,maximumSessions(1)是配置好了,然后去启动项目,然后你会发现登录同一个账号,并没有剔除前一个账号,这是怎么回事呢?
抛开框架暂且不说,如果是我直接写一个剔除前一个用户的话,我肯定是要得到全部用户,然后挨个挨个遍历筛选,如果存在当前登录用户就剔除前一个用户,这个需要使用if比较来实现的。
好了,问题找到了,因为SpringSecurity是通过管理UserDetails对象来实现用户管理的,按照上一步的原理,是需要进行比较实现效果的,然后呢,类的比较是不能用==比较的,类之间的比较是通过类的equals方法进行比较的,好了,问题找到了,我们自定义的User对象是没有实现equals方法的,好了,我们现在开始重写equals方法吧,关于重写的规则是:如果要重写equals方法,那么就必须要重写toStirng方法,如果要重写toString方法就最好要重写hashCode方法,所以我们需要在自定义的User对象中重写三个方法,hashCode、toString和equals方法。
public String toString() {
return this.userN
public int hashCode() {
return userName.hashCode();
public boolean equals(Object obj) {
return this.toString().equals(obj.toString());
下面是我自定义的User类(只是示例,没有配置权限相关):
import java.util.C
import org.springframework.security.core.GrantedA
import org.springframework.security.core.userdetails.UserD
import com.hong610.domain.U
* SpringSecurity User
* @author Hong
* @Date 日
public class UserDetail implements UserDetails {
private String userN
private String userP
private static final long serialVersionUID = 1L;
public UserDetail(User user) {
this.setUserName(user.getUserName());
this.setUserPwd(user.getUserPwd());
public Collection&? extends GrantedAuthority& getAuthorities() {
public String getPassword() {
return this.getUserPwd();
public String getUsername() {
return this.getUserName();
public boolean isAccountNonExpired() {
public boolean isAccountNonLocked() {
public boolean isCredentialsNonExpired() {
public boolean isEnabled() {
public String getUserName() {
return userN
public void setUserName(String userName) {
this.userName = userN
public String getUserPwd() {
return userP
public void setUserPwd(String userPwd) {
this.userPwd = userP
public String toString() {
return this.userN
public int hashCode() {
return userName.hashCode();
public boolean equals(Object obj) {
return this.toString().equals(obj.toString());
Okay,重启项目,剔除前一个用户成功!
关于重写的规则参照《Effective Java》书籍。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:435次
排名:千里之外使用spring security进行会话管理时,想实现一个类似单点登录功能(账号在一个地方登录了,另外一个地方就不能登录了),根据官方文档给定的例子进行,发现使用多个登录账号时,依旧能登录,网上也看了一些例子,稍微复杂一些的就是在spring的文件注册了sessi>
spring_security.zip (50.7 KB)
描述: 实现会话控制,权限控制,免登陆的spring security完整
下载次数: 0tianya23 的BLOG
用户名:tianya23
文章数:863
评论数:64
访问量:1891479
注册日期:
阅读量:5863
阅读量:12276
阅读量:394932
阅读量:1085809
51CTO推荐博文
由于ss2的demo配置太过简单,要想在项目中应用的话必须进行相应扩展,这里简单写一下简单的扩展方法。
xml头中引入security命名空间
&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-2.0.xsd&&
&&&&&&&&&&&&http://www.springframework.org/schema/security&http://www.springframework.org/schema/security/spring-security-2.0.xsd&&&
&&&&default-lazy-init=&true&&&&
&然后是启用ss2默认配置的一段代码
&&&&2.0新增的命名空间,使得配置简化了很多&&
&&&&auto-config&自动使用默认的配置&&
&&&&access-denied-page&指定访问未授权页面时显示的页面&&
&security:http&auto-config=&true&&access-denied-page=&/accessDenied.html&&&&
&&&&&security:anonymous&granted-authority=&BASIC&&/&&&
&/security:http&&&
&&这段代码作用是以ss2的默认配置方式加入1.0时需要手工配置的AuthenticationProcessingFilter等多个必须配置的filter,详细可参考1.0配置和2.0参考手册。
auto-config=&true& 表示使用ss2自动配置
access-denied-page=&/accessDenied.html&表示拒绝访问时显示的页面
&security:anonymous granted-authority=&BASIC& /&表示匿名权限的authority为BASIC
ss对权限的管理分为认证和授权两部分,先看认证
&&&&负责认证处理的filter&
&bean&id=&authenticationProcessingFilter&&&
&&&&class=&org.springframework.security.ui.webapp.AuthenticationProcessingFilter&&&&
&&&&&!--&此行说明此filter会覆盖ss2默认配置的filter,before&被覆盖filter的别名&--&&&
&&&&&security:custom-filter&before=&AUTHENTICATION_PROCESSING_FILTER&&/&&&
&&&&&!--&认证管理器&--&&&
&&&&&property&name=&authenticationManager&&ref=&authenticationManager&&/&&&
&&&&&!--&认证失败后跳转到的页面,/spring_security_login是ss2默认的登录入口&--&&&
&&&&&property&name=&authenticationFailureUrl&&&
&&&&&&&&value=&/spring_security_login&&/&&&
&&&&&!--&认证成功后跳转到的页面&--&&&
&&&&&property&name=&defaultTargetUrl&&value=&/index.html&&/&&&
&这是负责认证处理的filter,中间custom-filter一行意思是将filter放在默认配置中别名为AUTHENTICATION_PROCESSING_FILTER的filter前边,即负责认证的filter(别名列表参照参考手册)。
按官方的说法,如果需要用自定义的filter覆盖默认filter,则应该将security:http标签的auto-config属性改为false,这样的话就需要增加很多手动配置项。我试了下,不改false也可以,只是运行期间会出现一个warn信息&Possible error: Filters at position 2 and 3 are both instances of xxxx&,意思是filter串中有两个相同类型的filter。
另:在2.0.2中可以使用position代替before,真正的覆盖默认filter。但是有个bug,如果使用默认登录入口的话,还是会调用默认filter,必须连登录入口一并改掉。
其引用的authenticationManager
&&&&认证管理器&&
&&&&根据用户名和密码,使用多个provider进行认证&&
&&&&认证成功会生成一个Authentication,否则抛出AuthenticationException&&
&bean&id=&authenticationManager&&&
&&&&class=&org.springframework.security.providers.ProviderManager&&&&
&&&&&property&name=&providers&&&&
&&&&&&&&&list&&&
&&&&&&&&&&&&&ref&local=&daoAuthenticationProvider&&/&&&
&&&&&&&&&/list&&&
&&&&&/property&&&
&认证管理器通过多个provider实现基于用户名和密码的认证,多个provider中只要有一个认证成功,即成功。
这里只使用了一个daoPorvider
&&&&认证的provider&&
&&&&userDetailsService&根据用户名获取用户信息&&
&&&&userCache&ehcache缓存user信息。&&
&bean&id=&daoAuthenticationProvider&&&
&&&&class=&org.springframework.security.providers.dao.DaoAuthenticationProvider&&&&
&&&&&property&name=&userDetailsService&&ref=&userDetailsService&&/&&&
&&&&&property&name=&userCache&&ref=&userCache&&/&&&
userDetailsService:根据登录的用户名获取一个UserDetails,即代表一个用户的实体对象。
&!--&通过dao查询用户信息&--&&&
&bean&id=&userDetailsService&&&
&&&&class=&org.catspaw.ss2test1.security.UserDetailsSerivceImpl&&&&
&&&&&property&name=&userDao&&ref=&userDao&&/&&&
&UserDetailsSerivceImpl代码
Java代码&&
package&org.catspaw.ss2test1.&&
import&org.catspaw.ss2test1.dao.UserD&&
import&org.springframework.dao.DataAccessE&&
import&org.springframework.security.userdetails.UserD&&
import&org.springframework.security.userdetails.UserDetailsS&&
import&org.springframework.security.userdetails.UsernameNotFoundE&&
&*&获取UserDetails&
&*&使用UserDao查询User&
&*&@author&孙宁振&
public&class&UserDetailsSerivceImpl&implements&UserDetailsService&{&&
&&&&private&UserDao&userD&&
&&&&public&UserDao&getUserDao()&{&&
&&&&&&&&return&userD&&
&&&&public&void&setUserDao(UserDao&userDao)&{&&
&&&&&&&&this.userDao&=&userD&&
&&&&public&UserDetails&loadUserByUsername(String&username)&&
&&&&&&&&&&&&throws&UsernameNotFoundException,&DataAccessException&{&&
&&&&&&&&return&userDao.findByUsername(username);&&
&UserDao实现(接口省略)
Java代码&&
package&org.catspaw.ss2test1.dao.&&
import&java.util.L&&
import&org.catspaw.ss2test1.dao.UserD&&
import&org.catspaw.ss2test1.model.U&&
import&org.hibernate.criterion.DetachedC&&
import&org.hibernate.criterion.E&&
import&org.springframework.orm.hibernate3.support.HibernateDaoS&&
&*&查询User&
&*&@author&孙宁振&
public&class&UserDaoHibernate&extends&HibernateDaoSupport&implements&UserDao&{&&
&&&&public&User&get(String&id)&{&&
&&&&&&&&return&(User)&getHibernateTemplate().get(User.class,&id);&&
&&&&@SuppressWarnings(&unchecked&)&&
&&&&public&User&findByUsername(String&username)&{&&
&&&&&&&&DetachedCriteria&dc&=&DetachedCriteria.forClass(User.class);&&
&&&&&&&&dc.add(Expression.eq(&username&,&username));&&
&&&&&&&&List&User&&list&=&getHibernateTemplate().findByCriteria(dc);&&
&&&&&&&&if&(!list.isEmpty())&{&&
&&&&&&&&&&&&return&list.get(0);&&
&&&&&&&&}&&
&&&&&&&&return&&&
User实体,直接实现了UserDetails
Java代码&&
package&org.catspaw.ss2test1.&&
import&java.util.ArrayL&&
import&java.util.L&&
import&java.util.S&&
import&javax.persistence.E&&
import&javax.persistence.Id;&&
import&javax.persistence.JoinC&&
import&javax.persistence.JoinT&&
import&javax.persistence.ManyToM&&
import&javax.persistence.T&&
import&org.springframework.security.GrantedA&&
import&org.springframework.security.GrantedAuthorityI&&
import&org.springframework.security.userdetails.UserD&&
&*&实现了UserDetails&
&*&与Resource多对多关联&
&*&@author&孙宁振&
public&class&User&implements&UserDetails&{&&
&&&&private&String&&&&&&&&
&&&&private&String&&&&&&&&
&&&&private&String&&&&&&&&
&&&&private&Set&Resource&&&&
&&&&public&String&getId()&{&&
&&&&&&&&return&&&
&&&&public&String&getPassword()&{&&
&&&&&&&&return&&&
&&&&public&String&getUsername()&{&&
&&&&&&&&return&&&
&&&&@ManyToMany(targetEntity&=&Resource.class)&&
&&&&@JoinTable(name&=&&user_resource&,&joinColumns&=&@JoinColumn(name&=&&user_id&),&inverseJoinColumns&=&@JoinColumn(name&=&&resource_id&))&&
&&&&public&Set&Resource&&getResources()&{&&
&&&&&&&&return&&&
&&&&@Transient&&
&&&&public&GrantedAuthority[]&getAuthorities()&{&&
&&&&&&&&Set&Resource&&resources&=&getResources();&&
&&&&&&&&List&GrantedAuthority&&grandtedAuthorities&=&new&ArrayList&GrantedAuthority&(&&
&&&&&&&&&&&&&&&&resources.size());&&
&&&&&&&&for&(Resource&resource&:&resources)&{&&
&&&&&&&&&&&&String&authority&=&resource.getAuthority();&&
&&&&&&&&&&&&grandtedAuthorities.add(new&GrantedAuthorityImpl(authority));&&
&&&&&&&&}&&
&&&&&&&&return&grandtedAuthorities.toArray(new&GrantedAuthority[0]);&&
&&&&@Transient&&
&&&&public&boolean&isAccountNonExpired()&{&&
&&&&&&&&return&&&
&&&&@Transient&&
&&&&public&boolean&isAccountNonLocked()&{&&
&&&&&&&&return&&&
&&&&@Transient&&
&&&&public&boolean&isCredentialsNonExpired()&{&&
&&&&&&&&return&&&
&&&&@Transient&&
&&&&public&boolean&isEnabled()&{&&
&&&&&&&&return&&&
&&&&public&void&setId(String&id)&{&&
&&&&&&&&this.id&=&&&
&&&&public&void&setPassword(String&password)&{&&
&&&&&&&&this.password&=&&&
&&&&public&void&setUsername(String&username)&{&&
&&&&&&&&this.username&=&&&
&&&&public&void&setResources(Set&Resource&&resources)&{&&
&&&&&&&&this.resources&=&&&
&userCache缓存,都是使用的spring提供的实现。
&bean&id=&userCache&&&
&&&&class=&org.springframework.security.providers.dao.cache.EhCacheBasedUserCache&&&&
&&&&&property&name=&cache&&ref=&userCacheBacked&&/&&&
&bean&id=&userCacheBacked&&&
&&&&class=&org.springframework.cache.ehcache.EhCacheFactoryBean&&&&
&&&&&property&name=&cacheManager&&ref=&cacheManager&&/&&&
&&&&&property&name=&cacheName&&value=&myUserCache&&/&&&
&bean&id=&cacheManager&&&
&&&&class=&org.springframework.cache.ehcache.EhCacheManagerFactoryBean&&&&
&&&&&property&name=&configLocation&&value=&classpath:ehcache-security.xml&&/&&&
&ehcache-security.xml
&?xml&version=&1.0&&encoding=&UTF-8&?&&&
&ehcache&&&
&&&&&diskStore&path=&java.io.tmpdir/ehcache-security&&/&&&
&&&&&defaultCache&maxElementsInMemory=&10000&&eternal=&false&&&
&&&&&&&&timeToIdleSeconds=&120&&timeToLiveSeconds=&120&&overflowToDisk=&true&&&
&&&&&&&&diskPersistent=&false&&diskExpiryThreadIntervalSeconds=&120&&/&&&
&&&&&!--&security&cache--&&&
&&&&&cache&name=&myUserCache&&maxElementsInMemory=&10000&&eternal=&false&&&
&&&&&&&&overflowToDisk=&true&&timeToIdleSeconds=&1200&&timeToLiveSeconds=&7200&&&
&&&&&&&&diskPersistent=&false&&diskExpiryThreadIntervalSeconds=&120&&/&&&&&&&&&&&
&/ehcache&&&
&至此认证部分结束,下面是授权部分。
&filterSecurityInterceptor,虽然名叫interceptor,实际上是个filter,负责针对要访问的资源进行用户授权,同样也是覆盖默认实现。
&&&&负责授权的filter,检查Authentication所授予的权限是否可以访问被访问的资源&
&bean&id=&filterSecurityInterceptor&&&
&&&&class=&org.springframework.security.intercept.web.FilterSecurityInterceptor&&&&
&&&&&security:custom-filter&before=&FILTER_SECURITY_INTERCEPTOR&&/&&&
&&&&&property&name=&authenticationManager&&ref=&authenticationManager&&/&&&
&&&&&property&name=&accessDecisionManager&&ref=&accessDecisionManager&&/&&&
&&&&&!--&获取访问被访问的资源所需要的权限(authority)&--&&&
&&&&&property&name=&objectDefinitionSource&&&
&&&&&&&&ref=&databaseFilterInvocationDefinitionSource&&/&&&
&accessDecisionManager,授权管理器,通过多个voter投票判定是否授权,有多种决策机制实现(一票通过,半数通过,一票否决等),具体原理参见参考手册,这里使用的AffirmativeBased是一票通过制,即有一个voter投赞成票就授权。voter会取出当前登录用户的UserDetails的所有authority,与所访问url所对应的authority进行匹配,有相同就通过。
&&&&经过投票机制来决定是否可以访问某一资源&&
&&&&allowIfAllAbstainDecisions为false时如果有一个或以上的decisionVoters投票通过,则授权通过&&
&&&&其他可选的决策机制:&&
&&&&ConsensusBased&&
&&&&UnanimousBased&&
&bean&id=&accessDecisionManager&&&
&&&&class=&org.springframework.security.vote.AffirmativeBased&&&&
&&&&&property&name=&decisionVoters&&&&
&&&&&&&&&list&&&
&&&&&&&&&&&&&bean&class=&org.springframework.security.vote.RoleVoter&&&&
&&&&&&&&&&&&&&&&&property&name=&rolePrefix&&value=&&&/&&&
&&&&&&&&&&&&&/bean&&&
&&&&&&&&&/list&&&
&&&&&/property&&&
objectDefinitionSource,获得访问资源所必须具有的权限(authority)。这里和UserDetails的getAuthorities方法刚好相反。
&!--&获取访问被访问的资源所需要的权限(authority),以ConfigAttributeDefinition形式返回&--&&&
&bean&id=&databaseFilterInvocationDefinitionSource&&&
&&&&class=&org.springframework.security.intercept.web.DefaultFilterInvocationDefinitionSource&&&&
&&&&&!--&匹配url的matcher&--&&&
&&&&&constructor-arg&type=&org.springframework.security.util.UrlMatcher&&&
&&&&&&&&ref=&antUrlPathMatcher&&/&&&
&&&&&!--&url对应authority的map&--&&&
&&&&&constructor-arg&type=&java.util.LinkedHashMap&&ref=&requestMap&&/&&&
&!--ant&path风格的匹配器--&&&
&bean&id=&antUrlPathMatcher&&&
&&&&class=&org.springframework.security.util.AntUrlPathMatcher&&/&&&
requestMapFactoryBean,实现Spring的FactoryBean接口
这里在容器初始化时就查询所有url和authority的对应关系,保存为一个map,在认证操作时遍历这个map
Java代码&&
package&org.catspaw.ss2test1.&&
import&java.util.LinkedHashM&&
import&java.util.L&&
import&org.catspaw.ss2test1.dao.ResourceD&&
import&org.catspaw.ss2test1.model.R&&
import&org.springframework.beans.factory.FactoryB&&
import&org.springframework.security.ConfigA&&
import&org.springframework.security.ConfigAttributeD&&
import&org.springframework.security.SecurityC&&
import&org.springframework.security.intercept.web.RequestK&&
&*&产生一个map,包含所有url:authority的映射&
&*&key是resourceString(ant表达式,表示一个url集合)(如果是restful风格的应用,则key是url和method)&
&*&value是访问这些url所需要的权限(authority)&
&*&用于设置databaseFilterInvocationDefinitionSource中的requestMap&
&*&@author&孙宁振&
public&class&RequestMapFactoryBean&implements&FactoryBean&{&&
&&&&private&ResourceDao&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&resourceD&&
&&&&private&LinkedHashMap&RequestKey,&ConfigAttributeDefinition&&requestM&&
&&&&public&void&init()&{&&
&&&&&&&&requestMap&=&new&LinkedHashMap&RequestKey,&ConfigAttributeDefinition&();&&
&&&&&&&&List&Resource&&resources&=&resourceDao.findAll();&&
&&&&&&&&for&(Resource&resource&:&resources)&{&&
&&&&&&&&&&&&RequestKey&key&=&new&RequestKey(resource.getResourceString());//如果是restful风格的应用,则构造方法的参数应该是url和method&&
&&&&&&&&&&&&ConfigAttribute&attribute&=&new&SecurityConfig(resource&&
&&&&&&&&&&&&&&&&&&&&.getAuthority());&&
&&&&&&&&&&&&ConfigAttributeDefinition&definition&=&new&ConfigAttributeDefinition(&&
&&&&&&&&&&&&&&&&&&&&attribute);&&
&&&&&&&&&&&&requestMap.put(key,&definition);&&
&&&&&&&&}&&
&&&&public&Object&getObject()&throws&Exception&{&&
&&&&&&&&if&(requestMap&==&null)&{&&
&&&&&&&&&&&&init();&&
&&&&&&&&}&&
&&&&&&&&return&requestM&&
&&&&public&Class&getObjectType()&{&&
&&&&&&&&return&LinkedHashMap.&&
&&&&public&boolean&isSingleton()&{&&
&&&&&&&&return&&&
&&&&public&void&setResourceDao(ResourceDao&resourceDao)&{&&
&&&&&&&&this.resourceDao&=&resourceD&&
ResourceDao实现(接口省略)
Java代码&&
package&org.catspaw.ss2test1.dao.&&
import&java.util.L&&
import&org.catspaw.ss2test1.dao.ResourceD&&
import&org.catspaw.ss2test1.model.R&&
import&org.hibernate.criterion.DetachedC&&
import&org.hibernate.criterion.O&&
import&org.springframework.orm.hibernate3.support.HibernateDaoS&&
public&class&ResourceDaoHibernate&extends&HibernateDaoSupport&implements&&
&&&&&&&&ResourceDao&{&&
&&&&@SuppressWarnings(&unchecked&)&&
&&&&public&List&Resource&&findAll()&{&&
&&&&&&&&DetachedCriteria&criteria&=&DetachedCriteria.forClass(Resource.class);&&
&&&&&&&&criteria.addOrder(Order.desc(&resourceString&));&&
&&&&&&&&return&getHibernateTemplate().findByCriteria(criteria);&&
Resource实体
Java代码&&
package&org.catspaw.ss2test1.&&
import&java.io.S&&
import&java.util.S&&
import&javax.persistence.E&&
import&javax.persistence.Id;&&
import&javax.persistence.ManyToM&&
&*&与User多对多关联&
&*&@author&孙宁振&
public&class&Resource&implements&Serializable&{&&
&&&&private&String&&&&
&&&&private&String&&&&&&//ss中权限的标识符&&
&&&&private&String&&resourceS&//ant表达式,表示一个url集合&&
&&&&private&Set&User&&&&
&&&&public&String&getId()&{&&
&&&&&&&&return&&&
&&&&public&String&getAuthority()&{&&
&&&&&&&&return&&&
&&&&public&String&getResourceString()&{&&
&&&&&&&&return&resourceS&&
&&&&@ManyToMany(targetEntity&=&User.class,&mappedBy&=&&resources&)&&
&&&&public&Set&User&&getUsers()&{&&
&&&&&&&&return&&&
&&&&public&void&setId(String&id)&{&&
&&&&&&&&this.id&=&&&
&&&&public&void&setResourceString(String&resourceString)&{&&
&&&&&&&&this.resourceString&=&resourceS&&
&&&&public&void&setUsers(Set&User&&users)&{&&
&&&&&&&&this.users&=&&&
&&&&public&void&setAuthority(String&authority)&{&&
&&&&&&&&this.authority&=&&&
&最后,dao配置
&bean&id=&dataSource&&&
&&&&class=&org.springframework.jdbc.datasource.DriverManagerDataSource&&&&
&&&&&property&name=&driverClassName&&value=&com.mysql.jdbc.Driver&&/&&&
&&&&&property&name=&url&&value=&jdbc:mysql://localhost:3306/ss2test1&&/&&&
&&&&&property&name=&username&&value=&root&&/&&&
&&&&&property&name=&password&&value=&root&&/&&&
&bean&id=&abstractSessionFactory&&abstract=&true&&&&
&&&&&property&name=&dataSource&&ref=&dataSource&&/&&&
&&&&&property&name=&hibernateProperties&&&&
&&&&&&&&&props&&&
&&&&&&&&&&&&&prop&key=&hibernate.dialect&&&&
&&&&&&&&&&&&&&&&org.hibernate.dialect.MySQL5InnoDBDialect&&
&&&&&&&&&&&&&/prop&&&
&&&&&&&&&&&&&prop&key=&hibernate.show_sql&&true&/prop&&&
&&&&&&&&&&&&&prop&key=&hibernate.format_sql&&true&/prop&&&
&&&&&&&&&&&&&prop&key=&hibernate.hbm2ddl.auto&&none&/prop&&&
&&&&&&&&&/props&&&
&&&&&/property&&&
&!--&使用annotation方式描述的SessionFactory&--&&&
&bean&id=&sessionFactory&&&
&&&&class=&org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean&&&
&&&&parent=&abstractSessionFactory&&&&
&&&&&property&name=&configLocation&&value=&classpath:hibernate.cfg.xml&&/&&&
&bean&id=&baseDao&&abstract=&true&&&&
&&&&&property&name=&sessionFactory&&ref=&sessionFactory&&/&&&
&bean&id=&userDao&&&
&&&&class=&org.catspaw.ss2test1.dao.hibernate.UserDaoHibernate&&&
&&&&parent=&baseDao&&&&
&bean&id=&resourceDao&&&
&&&&class=&org.catspaw.ss2test1.dao.hibernate.ResourceDaoHibernate&&&
&&&&parent=&baseDao&&&&
hibernate配置文件 hibernate.cfg.xml
&?xml&version='1.0'&encoding='UTF-8'?&&&
&!DOCTYPE&hibernate-configuration&PUBLIC&&
&&&&&&&&&&&-//Hibernate/Hibernate&Configuration&DTD&3.0//EN&&&
&&&&&&&&&&&http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&&&&
&hibernate-configuration&&&
&&&&&session-factory&&&&&&&
&&&&&&&&&mapping&class=&org.catspaw.ss2test1.model.User&/&&&
&&&&&&&&&mapping&class=&org.catspaw.ss2test1.model.Resource&/&&&
&&&&&/session-factory&&&
&/hibernate-configuration&&&
本文只是一个最简单的示例,没有遵循rbac规范,仅仅是将user和resource关联起来,一个resource对应一个authority。也没有密码加密,cookie等功能,这些功能配置请参见参考手册。
在ss中,授权是以authority为基本单位的,user拥有多个authority,resource也可以拥有多个authority,在授权时只需要将user和resource的authority一一匹配即可。在实际应用中,可以在user和resource增加一层role来解耦,user-role-resource都是多对多关系,authority可以和role对应,授权时就变成了&检查用户是否具有访问某个资源所必须的角色&这一问题。
ss只提供认证和授权两个功能的实现,中间权限分配的实现由程序员负责,不管中间权限分配多么复杂,最后只要能将user和resource用authority关联起来就可以。
ss2常用的扩展点有以下几个:
UserDetails,表示一个用户实体,可以通过他来获得用户所具有的authority
AuthenticationProvider,用来认证一个用户Authentication,可以添加多个认证方式,比如sso
accessDecisionManager和Voter,用来对是否允许用户访问进行投票,以及投票的通过策略
objectDefinitionSource,用来获取资源和authority的对应,为用户授权提供依据。
基本上针对这三个扩展点进行相应扩展就可以满足大部分的应用需求。
2.0的整体架构和1.0相比基本没有改变,1.0时代的功能和配置方式也都可以继续使用,如果对ss2的默认配置不太放心,大可以把原来1.0的配置代码copy过来继续使用。
所用到的jar:spring2.0.7,hibernate3.2.5&jpa,spring-security2.0.3,ehcache1.3
数据库:mysql5,建好相应数据库后,把&prop key=&hibernate.hbm2ddl.auto&&none&/prop&的none改为create即可在运行时自动建表
登录入口为/spring_security_login
用户名&& 密码
admin&&& admin
aaa&&&&& aaa
bbb&&&&& bbb
&properties&
&slf4j-api.version&1.5.11&/slf4j-api.version&
&log4j.version&1.2.16&/log4j.version&
&slf4j-log4j12.version&1.5.6&/slf4j-log4j12.version&
&/properties&
&dependencies&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&misc.javassist&/artifactId&
&version&3.6&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&sourceforge.hibernate.annotations&/artifactId&
&version&3.4.0&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&mons.collections&/artifactId&
&version&3.2.1&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&mons-annotations&/artifactId&
&version&3.2.0.Final&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&java.j2ee&/artifactId&
&version&5&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&jdbc.mysql.mysql-connector&/artifactId&
&version&5.1.6&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&sourceforge.spring&/artifactId&
&version&2.5.6&/version&
&/dependency&
&!-- &dependency& &groupId&com.alibaba.external&/groupId& &artifactId&sourceforge.spring.security.core&/artifactId&&
&version&3.0.5.RELEASE&/version& &/dependency& --&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&sourceforge.spring.security.web&/artifactId&
&version&3.0.5.RELEASE&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&sourceforge.spring.security.core&/artifactId&
&version&2.0.4&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&sourceforge.spring.modules.context&/artifactId&
&version&2.5.6&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&sourceforge.ehcache&/artifactId&
&version&1.7.0&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&sourceforge.hibernate.annotations&/artifactId&
&version&3.4.0&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&sourceforge.hibernate.jpa-api&/artifactId&
&version&1.0.0.Final&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&sourceforge.hibernate.core&/artifactId&
&version&3.3.0&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&xml.dom4j&/artifactId&
&version&1.6.1&/version&
&/dependency&
&!-- log4j --&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&org.slf4j.slf4j-api&/artifactId&
&version&${slf4j-api.version}&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&jakarta.log4j&/artifactId&
&version&${log4j.version}&/version&
&/dependency&
&dependency&
&groupId&com.alibaba.external&/groupId&
&artifactId&org.slf4j.slf4j-log4j12&/artifactId&
&version&${slf4j-log4j12.version}&/version&
&/dependency&
&/dependencies&
&groupId&org.apache.maven.plugins&/groupId&
&artifactId&maven-compiler-plugin&/artifactId&
&configuration&
&source&1.6&/source&
&target&1.6&/target&
&encoding&UTF-8&/encoding&
&/configuration&
&/plugins&
了这篇文章
类别:┆阅读(0)┆评论(0)}

我要回帖

更多关于 security session 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信