`
孙宁振
  • 浏览: 35075 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类

spring security 2.0 的简单配置使用

阅读更多

 由于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" />
    </bean>

 这是负责认证处理的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>
    </bean>

 认证管理器通过多个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" />
    </bean>

 

userDetailsService:根据登录的用户名获取一个UserDetails,即代表一个用户的实体对象。

    <!-- 通过dao查询用户信息 -->
    <bean id="userDetailsService"
        class="org.catspaw.ss2test1.security.UserDetailsSerivceImpl">
        <property name="userDao" ref="userDao" />
    </bean>

 

 UserDetailsSerivceImpl代码

package org.catspaw.ss2test1.security;

import org.catspaw.ss2test1.dao.UserDao;
import org.springframework.dao.DataAccessException;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;

/**
 * 获取UserDetails
 * 使用UserDao查询User
 * 
 * @author 孙宁振
 *
 */
public class UserDetailsSerivceImpl implements UserDetailsService {

	private UserDao userDao;

	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		return userDao.findByUsername(username);
	}
}

 

 UserDao实现(接口省略)

package org.catspaw.ss2test1.dao.hibernate;

import java.util.List;
import org.catspaw.ss2test1.dao.UserDao;
import org.catspaw.ss2test1.model.User;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Expression;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * 查询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 null;
	}
}

 

User实体,直接实现了UserDetails

package org.catspaw.ss2test1.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Transient;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;

/**
 * 用户
 * 实现了UserDetails
 * 与Resource多对多关联
 * 
 * @author 孙宁振
 *
 */
@Entity
public class User implements UserDetails {

	private String		id;
	private String		username;
	private String		password;
	private Set<Resource> resources;

	@Id
	public String getId() {
		return id;
	}

	public String getPassword() {
		return password;
	}

	public String getUsername() {
		return username;
	}

	@ManyToMany(targetEntity = Resource.class)
	@JoinTable(name = "user_resource", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "resource_id"))
	public Set<Resource> getResources() {
		return resources;
	}

	@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 true;
	}

	@Transient
	public boolean isAccountNonLocked() {
		return true;
	}

	@Transient
	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Transient
	public boolean isEnabled() {
		return true;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public void setResources(Set<Resource> resources) {
		this.resources = resources;
	}
}

 

 userCache缓存,都是使用的spring提供的实现。

    <bean id="userCache"
        class="org.springframework.security.providers.dao.cache.EhCacheBasedUserCache">
        <property name="cache" ref="userCacheBacked" />
    </bean>
    <bean id="userCacheBacked"
        class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager" ref="cacheManager" />
        <property name="cacheName" value="myUserCache" />
    </bean>
    <bean id="cacheManager"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache-security.xml" />
    </bean>

 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" />
    </bean>

 

 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>
    </bean>

 

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" />
    </bean>
    <!--ant path风格的匹配器-->
    <bean id="antUrlPathMatcher"
        class="org.springframework.security.util.AntUrlPathMatcher" />

 

requestMapFactoryBean,实现Spring的FactoryBean接口

这里在容器初始化时就查询所有url和authority的对应关系,保存为一个map,在认证操作时遍历这个map

package org.catspaw.ss2test1.security;

import java.util.LinkedHashMap;
import java.util.List;
import org.catspaw.ss2test1.dao.ResourceDao;
import org.catspaw.ss2test1.model.Resource;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.SecurityConfig;
import org.springframework.security.intercept.web.RequestKey;

/**
 * 产生一个map,包含所有url:authority的映射
 * key是resourceString(ant表达式,表示一个url集合)(如果是restful风格的应用,则key是url和method)
 * value是访问这些url所需要的权限(authority)
 * 用于设置databaseFilterInvocationDefinitionSource中的requestMap
 * 
 * @author 孙宁振
 *
 */
public class RequestMapFactoryBean implements FactoryBean {

	private ResourceDao										  resourceDao;
	private LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap;

	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 requestMap;
	}

	public Class getObjectType() {
		return LinkedHashMap.class;
	}

	public boolean isSingleton() {
		return true;
	}

	public void setResourceDao(ResourceDao resourceDao) {
		this.resourceDao = resourceDao;
	}
}

 

ResourceDao实现(接口省略)

package org.catspaw.ss2test1.dao.hibernate;

import java.util.List;
import org.catspaw.ss2test1.dao.ResourceDao;
import org.catspaw.ss2test1.model.Resource;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

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实体

package org.catspaw.ss2test1.model;

import java.io.Serializable;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

/**
 * 资源
 * 与User多对多关联
 * 
 * @author 孙宁振
 *
 */
@Entity
public class Resource implements Serializable {

	private String	id;
	private String	authority;	  //ss中权限的标识符
	private String	resourceString; //ant表达式,表示一个url集合
	private Set<User> users;

	@Id
	public String getId() {
		return id;
	}

	public String getAuthority() {
		return authority;
	}

	public String getResourceString() {
		return resourceString;
	}

	@ManyToMany(targetEntity = User.class, mappedBy = "resources")
	public Set<User> getUsers() {
		return users;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void setResourceString(String resourceString) {
		this.resourceString = resourceString;
	}

	public void setUsers(Set<User> users) {
		this.users = users;
	}

	public void setAuthority(String authority) {
		this.authority = 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>

    <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>
    </bean>

    <!-- 使用annotation方式描述的SessionFactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
        parent="abstractSessionFactory">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
    </bean>

    <bean id="baseDao" abstract="true">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean id="userDao"
        class="org.catspaw.ss2test1.dao.hibernate.UserDaoHibernate"
        parent="baseDao">
    </bean>
    <bean id="resourceDao"
        class="org.catspaw.ss2test1.dao.hibernate.ResourceDaoHibernate"
        parent="baseDao">
    </bean>

 

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过来继续使用。

 

附demo
所用到的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

17
0
分享到:
评论
29 楼 nurenok 2010-08-24  
怎么清空缓存是个大问题。,LZ详细解释下。谢谢
28 楼 qqgoodluck 2009-01-03  
孙宁振 写道

qqgoodluck 写道
楼主如何实现动态的资源分配,当我角色可以访问的资源在数据库中发生变动时,如何动态影响到程序。刷新缓存,就是那个userCache,更改角色或资源的时候就清空缓存

谢谢回复,能否加一下我的QQ9975864
你后面的代码有涉及pass一个LinkedHashMap过去,如果我数据库里,角色与资源对应的表中数据发生了改变如何动态影响到系统呢?你后面的代码中的RequestHashMap中资源与角色对应的MAP没有存在缓存中吧?谢谢
27 楼 孙宁振 2008-12-27  
qqgoodluck 写道

楼主如何实现动态的资源分配,当我角色可以访问的资源在数据库中发生变动时,如何动态影响到程序。

刷新缓存,就是那个userCache,更改角色或资源的时候就清空缓存
26 楼 qqgoodluck 2008-12-22  
楼主如何实现动态的资源分配,当我角色可以访问的资源在数据库中发生变动时,如何动态影响到程序。
25 楼 wxlwxq 2008-12-10  
为什么我第一个用户登录后再退出,后面再登录的别的用户也只能进第一个用户能进的页面
24 楼 jillzhang 2008-11-19  
请问我按照您的配置,用了五个表,也是角色对应URL的,但好像永远只有一种角色能访问.
这种角色能访问的话,另一种角色即使有相应的权限也不能访问,是何原因呢?
23 楼 woodding2008 2008-11-06  
孙宁振 写道

bukebushuo 写道
不知道,怎么处理动态的URL,也就是在系统运行中,增加了URL-ROLE,怎样动态的反映到一开始就生成的Map中去?想动态增加url的话可以写一个RequestMap管理bean,把RequestMap注入给它,在需要的时候往map里增加就可以了。


请给段demo 代码。
22 楼 孙宁振 2008-10-26  
引用
楼主,能把你的lib jar包发给我吗?我邮箱wuhongyan008@163.com,先谢谢了

jar太大了,发不动,在框架的官方网站都有,下载相应版本即可
21 楼 孙宁振 2008-10-26  
引用
楼主,你的这种实现方法在每次服务器启动后就把resource表中所有的url对应的权限信息全部读入内存中,以后就不会再从数据库中读取信息了。我想请教两个问题
1.若数据库中resource表被更新了,怎么办呢?
2.若resource表中数据很多,那占用的内存是不是太多了点?

呵呵,我这只是个简单的demo,实际应用肯定不能这样的
1,更新时同时刷新cache
2,改成dao+cache实现
20 楼 wuhongyan008 2008-10-24  
楼主,你的这种实现方法在每次服务器启动后就把resource表中所有的url对应的权限信息全部读入内存中,以后就不会再从数据库中读取信息了。我想请教两个问题
1.若数据库中resource表被更新了,怎么办呢?
2.若resource表中数据很多,那占用的内存是不是太多了点?
19 楼 wuhongyan008 2008-10-23  
楼主,能把你的lib jar包发给我吗?我邮箱wuhongyan008@163.com,先谢谢了
18 楼 talangniao 2008-10-16  
是由于用户放置到缓存的缘故,增加用户、权限的时候没有清空缓存
17 楼 talangniao 2008-10-16  
Possible error: Filters at position 2 and 3 are both instances of

这个问题怎么不能去掉?难道没有影响嘛?
16 楼 talangniao 2008-10-15  
为什么设置url资源和权限后,需要从新启动tomcat,设置的用户才拥有相应的权限。  或者是修改某个用户的权限,并没有马上生效,拥有的权限还是原来的。重启tomcat后就生效。这到底是什么原因?
15 楼 qatang 2008-08-29  
高手高手高高手!经测试,成功!
14 楼 孙宁振 2008-08-29  
引用
又出现一个问题。当页面session超时后,我再点击的话,就会跳转到spring security自己默认的那个登录页面去了。怎么才能设定为自己的超时页??

这确实是个没考虑到的问题。。。
还是因为ss2的默认配置。里边有一个默认authenticationProcessingFilterEntryPoint,负责根据认证或授权抛出的异常跳转错误页。当认证过成中出现AuthenticationException的时候他会找默认的登录页面。
如果想自定义错误页的话得覆盖默认的authenticationProcessingFilterEntryPoint。
<security:http auto-config="true" access-denied-page="/accessDenied.html"
entry-point-ref="authenticationProcessingFilterEntryPoint">
加一个entry-point-ref,指向一个bean
<bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl"
value="/login.jsp" />
<property name="forceHttps" value="false" />
</bean>
这样当认证失败时就会跳到/login.jsp了
13 楼 qatang 2008-08-29  
又出现一个问题。当页面session超时后,我再点击的话,就会跳转到spring security自己默认的那个登录页面去了。怎么才能设定为自己的超时页??
12 楼 40020072 2008-08-20  
引用
access-denied-page="/error.jsp"



我试过是起作用的~

楼主的研究很棒~
11 楼 孙宁振 2008-08-19  
引用
access-denied-page="/error.jsp"没起作用,直接跳到resin的错误去了

resin没研究过,我用tomcat测试的
10 楼 qatang 2008-08-19  
<!--
        2.0新增的命名空间,使得配置简化了很多
        auto-config 自动使用默认的配置
        access-denied-page 指定访问未授权页面时显示的页面
    -->
    <security:http auto-config="true" access-denied-page="/error.jsp">
        <security:anonymous granted-authority="AU_BASIC" />
    </security:http>


access-denied-page="/error.jsp"没起作用,直接跳到resin的错误去了
403 Access is denied

Resin-3.0.25 (built Wed, 05 Dec 2007 08:19:34 PST) 


这是什么原因?谢谢

相关推荐

    Spring-Security2.0 和 3.0中文文档

    学习Spring Security 2.0 和 3.0 的中文文档,将帮助开发者深入理解如何配置和使用其核心组件,以及如何处理常见的安全问题。文档通常会包含详细的配置示例、API参考、教程和最佳实践,帮助开发者构建安全的Java应用...

    Spring Security 2.0.x完全中文参考文档

    包含了一系列简单的示例,用于演示如何配置和使用Spring Security。 - **3.2. Contacts** 通过这个示例展示如何在实际的应用场景中使用Spring Security。 - **3.3. LDAP例子** 展示了如何使用LDAP作为用户...

    spring security 2.0 的简单配置使用(补)——用aop控制method级权限

    在本文中,我们将深入探讨如何在Spring Security 2.0版本中配置并使用AOP(面向切面编程)来实现方法级别的权限控制。首先,我们需要理解Spring Security的基础概念。 1. **Spring Security基本架构** Spring ...

    spring security oauth2.0 (讲义+代码)

    Spring Security OAuth2.0 提供了 `ResourceServerConfigurerAdapter`,可以配置资源服务器的保护规则,如哪些URL需要令牌,以及如何验证令牌。 此外,Spring Security OAuth2.0 还支持自定义权限控制。通过实现`...

    spring2.0 security

    Spring Security 2.0允许开发者通过XML或Java配置进行高度定制。你可以自定义认证提供者、权限决策管理器、访问决策投票器,甚至可以完全替换默认的过滤器链。这种灵活性使得Spring Security能够适应各种复杂的应用...

    spring security 2.0 命名空间配置(带例子)

    通过SpringSecurityTest这个压缩包文件,你可以找到相关的示例代码和配置,以帮助你更好地理解这些概念。动手实践是学习Spring Security的最佳途径,你可以尝试修改配置,观察不同设置对应用程序安全行为的影响。 ...

    spring cloud2.0 eureka server spring security配置

    在Spring Cloud 2.0版本中,Eureka Server的配置相比1.x版本确实有了一些显著的变化,尤其是在结合Spring Security进行安全设置时。Spring Cloud Eureka是Netflix Eureka的Spring Boot实现,它为微服务架构提供了...

    Spring Security 2.0 中文参考文档

    **Spring Security 2.0 知识点详解** Spring Security 是一个强大且高度可定制的权限访问控制框架,主要用于Java应用程序的安全性管理。在2.0版本中,它提供了全面的解决方案来保护Web应用程序免受各种安全威胁。...

    spring security 2.0 连接数据库 简单的配置

    终于实现了spring security 2.0 基于数据库的配置,可以连接数据库了,呵呵,由于加入了spring,jar包有些大,没有上传jar,或者新建一个工程,加入spring,然后将jar考过来或者从其他模块中考入jar, 这个工程下的...

    Spring Security 2.0.x Sample Code

    在`springsecurity-sample`中,你将找到实际的代码实现,如配置文件、控制器、服务和DAO,展示了如何将这些概念应用于实际项目。通过对这些示例的分析和学习,你可以更好地理解和实践Spring Security 2.0.x的安全...

    Spring Security 2.0 参考手册.pdf

    在Spring Security 2.0的时代,这个框架已经非常成熟,为开发者提供了许多关键功能,如身份验证、授权、访问控制以及会话管理。以下是对Spring Security 2.0的一些核心知识点的详细解释: 1. **身份验证**:Spring ...

    Springsecurity2.0

    对于那些不希望使用XML的开发者,Spring Security 2.0引入了基于Java的配置API,使得配置过程更加直观和模块化。 综上所述,Spring Security 2.0为开发者提供了一套全面、灵活且易于使用的安全框架,无论是在小型...

    Acegi(Spring Security2.0)的PPT

    Acegi,现已被Spring Security 2.0完全取代,是Java应用程序的一个安全框架,主要用于实现企业级应用的安全控制。这个框架提供了丰富的功能,包括用户登录提示、身份验证、权限检查、访问控制、会话管理以及与各种...

    spring security + oauth 2.0 实现单点登录、认证授权

    Spring Security和OAuth 2.0是两个在Web应用安全领域广泛应用的框架,它们结合使用可以构建强大的单点登录(SSO)和认证授权系统。在这个系统中,`xp-sso-server`代表了认证服务器,而`xp-sso-client-a`和`xp-sso-...

    Learning Spring boot 2.0

    本书可能涵盖了自动配置、起步依赖、健康检查、Actuator监控、Spring Data、Spring Security等核心概念。自动配置是Spring Boot的一大亮点,它可以根据项目中的依赖自动配置相关组件,极大地减少了手动配置的工作量...

    Spring Security OAuth 2.0

    使用 Spring Security OAuth 2.0,可以快速构建 OAuth 2.0 验证和授权系统。 首先,需要创建一个 Spring Boot 项目,然后添加 Spring Security OAuth 2.0 依赖项。接下来,需要配置 OAuth 2.0 配置,包括客户端配置...

    视频配套笔记_Spring Security OAuth2.0认证授权_v1.1.rar

    Spring Security OAuth2.0 是一个广泛使用的Java安全框架,它为构建安全的Web应用程序提供了强大的支持。OAuth2.0是授权框架的一个标准,允许第三方应用在用户授权的情况下访问其私有资源,而无需共享用户的登录凭证...

    spring security 2.0 安全框架实例(改进版)

    从Spring-2.0开始可以使用命名空间的配置方式。 使用它呢,可以通过附加xml架构,为传统的spring beans应用环境语法做补充。 你可以在spring参考文档得到更多信息。 命名空间元素可以简单的配置单个bean,或使用更...

    Spring Security OAuth2.0

    使用Spring Security OAuth2.0时,需要配置`http`元素以保护URL,设置过滤器链,如`OAuth2AuthenticationProcessingFilter`和`OAuth2AccessDeniedHandler`,确保只有持有有效令牌的请求才能访问受保护的资源。...

Global site tag (gtag.js) - Google Analytics