<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd
">
<bean id="filterChain"
class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**"
filters="formValidateCodeFilter,
mySessionValidateFilter,
myRempassFilter,
securityContextPersistenceFilter,
channelProcessingFilter,
logoutFilter,
usernamePasswordAuthenticationFilter,
rememberMeAuthenticationFilter,
anonymousAuthenticationFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</security:filter-chain-map>
</bean>
<bean id="mySessionValidateFilter"
class="com.xxx.framework.security.filter.MySessionValidateFilter">
<property name="excludePath" value="${sec.excludePath}"/>
<property name="filterIndexUrl" value="${sec.indexUrl}"/>
</bean>
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
<bean id="channelProcessingFilter"
class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
<property name="channelDecisionManager" ref="channelDecisionManagerImpl"/>
<property name="securityMetadataSource" ref="myDefaultFilterInvocationSecurityMetadataSource"/>
</bean>
<bean id="channelDecisionManagerImpl"
class="org.springframework.security.web.access.channel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<ref bean="secureChannelProcessor"/>
<ref bean="insecureChannelProcessor"/>
</list>
</property>
</bean>
<bean id="secureChannelProcessor"
class="org.springframework.security.web.access.channel.SecureChannelProcessor">
<property name="entryPoint" ref="channelEntryPoint"/>
</bean>
<bean id="channelEntryPoint"
class="org.springframework.security.web.access.channel.RetryWithHttpsEntryPoint">
<property name="portMapper" ref="portMapperImpl"/>
</bean>
<bean id="portMapperImpl"
class="org.springframework.security.web.PortMapperImpl" scope="prototype">
<property name="portMappings">
<map>
<entry key="${init.httpPort}"><value>${init.httpsPort}</value></entry>
</map>
</property>
</bean>
<bean id="myDefaultFilterInvocationSecurityMetadataSource"
class="com.xxx.framework.security.common.MyDefaultFilterInvocationSecurityMetadataSource">
<constructor-arg type="org.springframework.security.web.util.UrlMatcher" ref="urlMatcher" />
</bean>
<bean id="insecureChannelProcessor"
class="org.springframework.security.web.access.channel.InsecureChannelProcessor">
<property name="entryPoint" ref="channelEntryPointHttp"/>
</bean>
<bean id="channelEntryPointHttp"
class="org.springframework.security.web.access.channel.RetryWithHttpEntryPoint">
<property name="portMapper" ref="portMapperImpl"/>
</bean>
<bean id="rememberMeAuthenticationFilter"
class="com.xxx.framework.security.filter.MyRememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="authenticationManager" />
<property name="filterProcessesUrl" value="${sec.mainUrl}"/>
<property name="filterExcludeUrl" value="${sec.excPath}"/>
<property name="authorizationService" ref="authorizationService"></property>
</bean>
<bean id="rememberMeServices"
class="com.xxx.framework.security.common.MyBasedRememberMeServices">
<property name="key" value="ke4-espa?uFraz5muphuqemayut2cefreqefr-swuqunu6ag"/>
<property name="tokenValiditySeconds" value="${sec.cookieTime}"/>
<property name="myUserDetailsService" ref="jdbcUserService"/>
<property name="parameter" value="rempass"/>
<property name="cookieName" value="name"/>
</bean>
<bean id="jdbcRememberMeTokenRepository"
class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="ke4-espa?uFraz5muphuqemayut2cefreqefr-swuqunu6ag"/>
</bean>
<bean id="anonymousAuthenticationFilter"
class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
<property name="userAttribute" value="anonymousUser,anonymous}"/>
<property name="key" value="BF93JFJ091N00Q7HF"/>
</bean>
<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/> <!--ss会判断当前的请求是否已经通过登录的,当没有通过登录的,authenticationManager ss会做登录鉴权认证-->
<property name="accessDecisionManager" ref="affirmativeBased"/>
<property name="securityMetadataSource" ref="filterInvocationDefinitionSource" /><!--securityMetadataSource这个数据源中有个Map结构存放。所有的角色对应的权限这里根据项目需要,我们这是是自定义的,下面的filterInvocationDefinitionSource-->
</bean>
<bean id="filterInvocationDefinitionSource"
class="com.xxx.framework.security.common.MyJdbcFilterInvocationDefinitionSourceFactoryBean">
<constructor-arg type="org.springframework.security.web.util.UrlMatcher" ref="urlMatcher" />
<constructor-arg type="com.xxx.portal.security.service.AuthorizationService" ref="authorizationService" />
</bean>
<bean id="urlMatcher"
class="org.springframework.security.web.util.AntUrlPathMatcher" >
<constructor-arg type="boolean" value="true" />
</bean>
<bean class="org.springframework.security.access.vote.AffirmativeBased" id="affirmativeBased">
<property name="decisionVoters">
<list>
<ref bean="roleVoter"/>
</list>
</property>
</bean>
<bean class="com.xxx.framework.security.common.MyRoleVoter" id="roleVoter"></bean><!--自定义Voter代码如下已贴出-->
<bean id="daoAuthenticationProvider" class="com.xxx.framework.security.common.MyDaoAuthenticationProvider">
<property name="userDetailsService" ref="jdbcUserService"/>
<property name="passwordEncoder" ref="passwordEncoder"/>
<property name="saltSource" ref="saltSource"/>
</bean>
<bean id="anonymousAuthenticationProvider" class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
<property name="key" value="BF93JFJ091N00Q7HF"/>
</bean>
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
<ref local="anonymousAuthenticationProvider"/>
<ref local="rememberMeAuthenticationProvider"/>
</list>
</property>
</bean>
<bean id="jdbcUserService"
class="com.xxx.framework.security.common.MyCustomJdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
<property name="enableGroups" value="true"/>
<property name="enableAuthorities" value="false"/>
<property name="passwordEncoder" ref="passwordEncoder"/>
<property name="saltSource" ref="saltSource"/>
<property name="authorizationService" ref="authorizationService"/>
</bean>
<bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
<property name="userPropertyToUse" value="userId"/>
</bean>
<bean id="usernamePasswordAuthenticationFilter"
class="com.xxx.framework.security.filter.MyFormUsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler"></property>
<property name="authenticationFailureHandler" ref="accessAuthenticationFailureHandler"></property>
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
<bean id="loginLogAuthenticationSuccessHandler"
class="com.xxx.framework.security.common.MyFormSimpleUrlAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="${sec.mainUrl}"></property>
<property name="authorizationService" ref="authorizationService"></property>
</bean>
<bean id="myLoginLogAuthenticationSuccessHandler"
class="com.xxx.framework.security.common.MySimpleUrlAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="${sec.mainUrl}"></property>
</bean>
<bean id="accessAuthenticationFailureHandler"
class="com.xxx.framework.security.common.MyAccessAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="${sec.indexUrl}"></property>
</bean>
<bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="${sec.indexUrl}"></property>
</bean>
<bean id="formValidateCodeFilter"
class="com.xxx.framework.security.filter.MyFormValidateCodeFilter">
<property name="filterIndexUrl" value="${sec.indexUrl}"/>
<property name="filterProcessesUrl" value="${sec.loginUrl}"/>
</bean>
<bean id="myRempassFilter"
class="com.xxx.framework.security.filter.MyRempassFilter">
<property name="tokenValiditySeconds" value="${sec.cookieTime}"/>
<property name="filterProcessesUrl" value="${sec.loginUrl}"/>
</bean>
<!--exceptionTranslationFilter用来对AuthenticationException和AccessDeniedException异常的处理。-->
<bean id="exceptionTranslationFilter"
class="com.xxx.framework.security.filter.MyExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
<property name="accessDeniedHandler" ref="accessDeniedHandler"/>
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="${sec.indexUrl}"/>
</bean>
<bean id="accessDeniedHandler"
class="com.xxx.framework.security.common.MyAccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.action"/>
</bean>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg ref="logoutSuccessHandler"/>
<constructor-arg>
<array>
<ref local="logoutHandler"/>
<ref local="rememberMeServices"/>
</array>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout.action"/>
</bean>
<bean id="logoutHandler" class="com.xxx.framework.security.common.MySecurityContextLogoutHandler">
<property name="authorizationService" ref="authorizationService"></property>
</bean>
<bean id="logoutSuccessHandler" class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler">
<property name="defaultTargetUrl" value="/exitSystem.action"/>
</bean>
</beans>
package com.xxx.framework.security.common;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
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.RequestKey;
import org.springframework.security.web.util.UrlMatcher;
import com.xxx.portal.security.service.AuthorizationService;
import com.xxx.portal.security.vo.Resource;
public class MyJdbcFilterInvocationDefinitionSourceFactoryBean extends
DefaultFilterInvocationSecurityMetadataSource
{
public MyJdbcFilterInvocationDefinitionSourceFactoryBean(
UrlMatcher urlMatcher, AuthorizationService authorizationService)
{
super(urlMatcher, getRequestMap(authorizationService));
setStripQueryStringFromUrls(true);
}
/**
* url权限封装这里是封装的所有的资源对应的角色。
*/
private static LinkedHashMap<RequestKey, Collection<ConfigAttribute>> getRequestMap(
AuthorizationService authorizationService)
{
LinkedHashMap<RequestKey, Collection<ConfigAttribute>> resourceMap = new LinkedHashMap<RequestKey, Collection<ConfigAttribute>>();
for (Resource resource : (List<Resource>) authorizationService
.queryPathMapping())
{
String url = resource.getUrl();
RequestKey request = new RequestKey("/" + url);
String role = resource.getRole();
if (resourceMap.containsKey(request))
{
Collection list = resourceMap.get(request);
list.add(new SecurityConfig(role));
resourceMap.put(request, list);
}
else
{
Collection attributes = new ArrayList();
attributes.add(new SecurityConfig(role));
resourceMap.put(request, attributes);
}
}
return resourceMap;
}
}
import java.util.Collection;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
public class MyRoleVoter implements AccessDecisionVoter
{
public boolean supports(ConfigAttribute attribute)
{
return true;
}
public boolean supports(Class<?> clazz)
{
return true;
}
//下面是投票的关键代码,入参authentication是当前登录用户的角色,attributes是当前用户访问的资源(这里指/xx.aciton)所应该具有的角色。attributes有springsecurity框架获取到。
//下面代码的主要逻辑就是看当前用户的是不是具体访问该资源的角色。如果有则放行,没有则被exceptionTranslationFilter捕获,跳转到访问拒绝提示页面。
Collection<ConfigAttribute> attributes)
{
int result = ACCESS_ABSTAIN;
Collection<GrantedAuthority> authorities = extractAuthorities(authentication);
for (ConfigAttribute attribute : attributes)
{
if (this.supports(attribute))
{
result = ACCESS_DENIED;
for (GrantedAuthority authority : authorities)
{
if (attribute.getAttribute()
.equals(authority.getAuthority()))
{
return ACCESS_GRANTED;
}
}
}
}
return result;
}
Collection<GrantedAuthority> extractAuthorities(
Authentication authentication)
{
return authentication.getAuthorities();
}
}