SpringSecurity3.0.5的配置文件及相关类的源代码

本文详细介绍了 Spring Security 的配置方法,包括 HTTP 安全配置、登录与注销配置、自定义 Filter 配置等关键环节,并展示了如何通过 Bean 定义用户服务、权限决策管理器等核心组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:s="http://www.springframework.org/schema/security"
        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"
    default-lazy-init="true">
<!-- TODO 原来Spring2.5和SpringSecurity2.0.4的文件头
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:s="http://www.springframework.org/schema/security"
        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-2.5.xsd
            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"
    default-autowire="autodetect" default-lazy-init="true">
 -->

    <description>SpringSecurity安全配置</description>

    <!-- http安全配置 -->
    <s:http auto-config="true" use-expressions="true">
       <!-- 对登录页面不进行拦截,至于后面的*,是因为请求的页面可能包含一些参数! -->
       <s:intercept-url pattern="/login.jsp*" filters="none"/>
       <!-- TODO
       <s:intercept-url pattern="/login" access="hasAnyRole('IS_AUTHENTICATED_ANONYMOUSLY')"/>
       <s:intercept-url pattern="/**" access="hasAnyRole('ROLE_数据模块')"/> -->
   
       <s:intercept-url pattern="/style/**" filters="none"/>
       <s:intercept-url pattern="/image/**" filters="none"/>
       <s:intercept-url pattern="/script/**" filters="none"/>
       <s:intercept-url pattern="/fckeditor/**" filters="none"/>
       <s:intercept-url pattern="/decorators/**" filters="none"/>
       <s:intercept-url pattern="/uploads/**" filters="none"/>
       <s:intercept-url pattern="/common/**" filters="none"/>

<!-- TODO 若不配置权限,则以匿名用户访问所有页面!
       <s:intercept-url pattern="/activity_publicize/activity-publicize!save*" access="hasAnyRole('ROLE_修改活动宣传')"/>
       <s:intercept-url pattern="/activity_publicize/activity-publicize!delete*" access="hasAnyRole('ROLE_修改活动宣传')"/>
       <s:intercept-url pattern="/activity_publicize/activity-publicize*" access="hasAnyRole('ROLE_浏览活动宣传')"/> -->
      
       <!-- 配置登录页面!
       <s:form-login login-page="/login" default-target-url="/index/main" authentication-failure-url="/index/main"/> -->
       <s:form-login login-page="/login" default-target-url="/index.jsp" authentication-failure-url="/login?error=true"/>
       <s:logout logout-success-url="/index.jsp"/>
      
       <!-- TODO 在SS3.0.x中,自定义的filter的配置要放在s:http里 -->
       <s:custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/>
    </s:http>
    <!--<s:http auto-config="true" access-decision-manager-ref="accessDecisionManager">
        <s:form-login login-page="/logreg.action" default-target-url="/"
            authentication-failure-url="/logreg.action?error=true" />
        <s:logout logout-success-url="/" />
        <s:remember-me key="e37f4b31-0c45-11dd-bd0b-0800200c9a66" />
    </s:http>-->
   
    <!-- 认证配置,使用userDetailsService提供的用户信息 -->
    <s:authentication-manager alias="authenticationManager">
        <s:authentication-provider user-service-ref="userDetailsService">
            <!-- TODO 可设置hash使用sha1或md5散列密码后再存入数据库 -->
            <s:password-encoder hash="plaintext"></s:password-encoder>
        </s:authentication-provider>
    </s:authentication-manager>

    <!-- 项目实现的用户查询服务 -->
    <bean id="userDetailsService" class="com.byd.info_platform.service.account.UserDetailsServiceImpl" />
   
    <!--JCaptcha验证码服务
    <bean id="captchaService" class="com.octo.captcha.service.image.DefaultManageableImageCaptchaService">
        <property name="captchaEngine">
            <bean class="com.zenithen.skynet.skynet.security.jcaptcha.GMailEngine" />
        </property>
        默认生成的图片180秒过期 , 可另行设置
        <property name="minGuarantedStorageDelayInSeconds" value="180" />
    </bean> -->

    <!-- 重新定义的FilterSecurityInterceptor,使用databaseDefinitionSource提供的url-授权关系定义 --><!-- <bean id="filterSecurityInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor"> SpringSecurity2.0.x中使用 -->
    <bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
        <!--<s:custom-filter before="FILTER_SECURITY_INTERCEPTOR" />
        <s:custom-filter ref="databaseDefinitionSource" before="FILTER_SECURITY_INTERCEPTOR"/>-->
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="accessDecisionManager" ref="accessDecisionManager" />
        <property name="securityMetadataSource" ref="databaseDefinitionSource" /><!-- <property name="objectDefinitionSource" ref="databaseDefinitionSource" /> 注:objectDefinitionSource在SS3中已经标记为过时了,要换用securityMetadataSource -->
    </bean>
   
    <!-- DefinitionSource工厂,使用resourceDetailsService提供的URL-授权关系.
    <bean id="databaseDefinitionSource" class="com.zenithen.skynet.security.springsecurity.DefinitionSourceFactoryBean"> -->
    <bean id="databaseDefinitionSource" class="com.byd.info_platform.service.account.DefinitionSourceFactoryBean">
        <property name="resourceDetailsService" ref="resourceDetailsService" />
    </bean>

    <!-- 项目实现的URL-授权查询服务 -->
    <bean id="resourceDetailsService" class="com.byd.info_platform.service.account.ResourceDetailsServiceImpl" />
   
    <!-- 授权判断配置, 将授权名称的默认前缀由ROLE_改为A_. --><!-- <bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased"> SpringSecurity2.0.x中使用 -->
    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="decisionVoters">
            <list><!-- <bean class="org.springframework.security.vote.RoleVoter"> SpringSecurity2.0.x中使用 -->
                <bean class="org.springframework.security.access.vote.RoleVoter">
                    <property name="rolePrefix" value="A_" />
                </bean><!-- <bean class="org.springframework.security.vote.AuthenticatedVoter" /> SpringSecurity2.0.x中使用 -->
                <bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
            </list>
        </property>
    </bean>
</beans>

 

DefinitionSourceFactoryBean类和ResourceDetailsServiceImpl类

/**
 * Copyright (c) 2005-2009 springside.org.cn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * 
 * $Id: DefinitionSourceFactoryBean.java 619 2009-11-03 16:38:04Z calvinxiu $
 */
package com.byd.info_platform.service.account;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.RequestKey;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;

/**
 * DefinitionSource工厂.
 * 
 * 由注入的resourceDetailService读取在数据库或其它地方中定义的URL-授权关系, 提供LinkedHashMap<String,
 * String>形式的URL及授权关系定义, 并最终转为SpringSecurity所需的LinkedHashMap<RequestKey,
 * Collection<ConfigAttribute>>形式的定义.
 * 
 * @see org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource
 * @see ResourceDetailsService
 * 
 * @author calvin
 * @author leeoo
 */
public class DefinitionSourceFactoryBean implements FactoryBean {

	private ResourceDetailsService resourceDetailsService;

	public void setResourceDetailsService(ResourceDetailsService resourceDetailsService) {
		this.resourceDetailsService = resourceDetailsService;
	}

	/**
	 * 返回注入了AntStyle的URLMatcher和ResourceDetailService提供的RequestMap的DefaultFilterInvocationSecurityMetadataSource.
	 */
	public Object getObject() throws Exception {
	    // 3.x之前的版本使用~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//		LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap = buildRequestMap();
//		UrlMatcher matcher = getUrlMatcher();
//		DefaultFilterInvocationDefinitionSource definitionSource = new DefaultFilterInvocationDefinitionSource(matcher,
//				requestMap);
	    // 3.x之前的版本使用~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		LinkedHashMap<RequestKey, Collection<ConfigAttribute>> requestMap = buildRequestMap();
		UrlMatcher matcher = getUrlMatcher();
		DefaultFilterInvocationSecurityMetadataSource definitionSource = new DefaultFilterInvocationSecurityMetadataSource(matcher,
		        requestMap);
		return definitionSource;
	}

	/**
	 * @see FactoryBean#getObjectType()
	 */
	public Class getObjectType() {
//		return FilterInvocationDefinitionSource.class; // 3.x之前的版本使用
		return FilterInvocationSecurityMetadataSource.class;
	}

	/**
	 * @see FactoryBean#isSingleton()
	 */
	public boolean isSingleton() {
		return true;
	}

	/**
	 * 提供Ant Style的URLMatcher.
	 */
	protected UrlMatcher getUrlMatcher() {
		return new AntUrlPathMatcher();
	}

	/**
	 * 将resourceDetailService提供LinkedHashMap<String, String>形式的URL及授权关系定义
	 * 转化为DefaultFilterInvocationSecurityMetadataSource需要的LinkedHashMap<RequestKey,
	 * Collection<ConfigAttribute>>形式.
	 */
	// 注:SpringSecurity3里面修改了几个类,其中的ConfigAttributeEditor类已过时,改用SecurityConfig类了;ConfigAttributeDefinition类已废弃
    protected LinkedHashMap<RequestKey, Collection<ConfigAttribute>> buildRequestMap() throws Exception {// NOSONAR
        LinkedHashMap<String, String> srcMap = resourceDetailsService.getRequestMap();

        LinkedHashMap<RequestKey, Collection<ConfigAttribute>> distMap = new LinkedHashMap<RequestKey, Collection<ConfigAttribute>>();
        for (Map.Entry<String, String> entry : srcMap.entrySet()) {
            RequestKey key = new RequestKey(entry.getKey(), null);
            Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
            atts = SecurityConfig.createListFromCommaDelimitedString(entry.getValue());
            distMap.put(key, atts);
        }

        return distMap;
    }
    
	/*
	// 3.x之前的版本使用如下写法
	protected LinkedHashMap<RequestKey, Collection<ConfigAttribute>> buildRequestMap() throws Exception {
 // protected LinkedHashMap<RequestKey, ConfigAttributeDefinition> buildRequestMap() throws Exception { // 3.x之前的版本使用
		LinkedHashMap<String, String> srcMap = resourceDetailsService.getRequestMap();
		LinkedHashMap<RequestKey, Collection<ConfigAttribute>> distMap = new LinkedHashMap<RequestKey, Collection<ConfigAttribute>>();
//		LinkedHashMap<RequestKey, ConfigAttributeDefinition> distMap = new LinkedHashMap<RequestKey, ConfigAttributeDefinition>(); // 3.x之前的版本使用
		ConfigAttributeEditor editor = new ConfigAttributeEditor();

		for (Map.Entry<String, String> entry : srcMap.entrySet()) {
			RequestKey key = new RequestKey(entry.getKey(), null);
			if (StringUtils.isNotBlank(entry.getValue())) {
				editor.setAsText(entry.getValue());
//				distMap.put(key, (ConfigAttributeDefinition) editor.getValue()); // 3.x之前的版本使用
				distMap.put(key, (Collection<ConfigAttribute>) editor.getValue());
			} else {
//				distMap.put(key, ConfigAttributeDefinition.NO_ATTRIBUTES); // 3.x之前的版本使用
//				distMap.put(key, ConfigAttribute.NO_ATTRIBUTES); // 3.x之前的版本使用
			}
		}

		return distMap;
	}
*/
}

/**
 * 
 */
package com.byd.info_platform.service.account;

import java.util.LinkedHashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.byd.info_platform.entity.account.Resource;

/**
 * 从数据库查询URL--授权定义Map的实现类.
 * 
 */
@Transactional(readOnly = true)
public class ResourceDetailsServiceImpl implements ResourceDetailsService {

    private AccountManager accountManager;

    /**
     * @see ResourceDetailsService#getRequestMap()
     */
    public LinkedHashMap<String, String> getRequestMap() throws Exception {//NOSONAR
        List<Resource> resourceList = accountManager.getUrlResourceWithAuthorities();

        LinkedHashMap<String, String> requestMap = new LinkedHashMap<String, String>(resourceList.size());
        for (Resource resource : resourceList) {
            requestMap.put(resource.getValue(), resource.getAuthNames());
        }
        return requestMap;
    }

    @Autowired
    public void setAccountManager(AccountManager accountManager) {
        this.accountManager = accountManager;
    }

}

转载于:https://my.oschina.net/leeoo/blog/37863

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值