SS 的版本是2.0.5。
我採用的是authentication 是從ldap進行,authorization是根據數據庫的role,resource,user以及他們之間關聯表進行。
需要注意的是,如果要對所有的資源進行過濾,可以繼承anonymousProcessingFilter。
兩個配置文件,
web.xml 這個沒的說。
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
version="2.4">
<display-name>SkillDB</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<!-- Configure filter of spring -->
<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>
<!-- Configure the core filter of struts -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- session config -->
<session-config>
<!-- Default to 30 minutes session timeouts -->
<session-timeout>2</session-timeout>
</session-config>
<!-- Configure the srping context -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
********
application-security.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-2.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
<!--
<http> <intercept-url pattern="/login.jsp" filters="none"/>
<intercept-url pattern="/**" access="ROLE_COMMON_USER"/> <form-login
login-page="/login.jsp"/> </http>
-->
<beans:bean id="springSecurityFilterChain"
class="org.springframework.security.util.FilterChainProxy">
<beans:property name="filterInvocationDefinitionSource">
<beans:value>
<![CDATA[ CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
]]>
</beans:value>
</beans:property>
</beans:bean>
<beans:bean id="httpSessionContextIntegrationFilter"
class="org.springframework.security.context.HttpSessionContextIntegrationFilter">
<beans:property name="contextClass">
<beans:value>org.springframework.security.context.SecurityContextImpl
</beans:value>
</beans:property>
</beans:bean>
<!--
<beans:bean id="sessionTimeoutFilter"
class="com.bleum.javateam.skilldb.security.service.SessionTimeoutFilter">
<custom-filter before="CONCURRENT_SESSION_FILTER" /> </beans:bean>
-->
<!--
<ldap-server id="contextSource"
url="ldap://cn.bleum.com:389/OU=Bleum,DC=cn,DC=bleum,DC=com"
manager-dn="(CN={0}),OU=JavaBench,OU=Development,OU=Bleum,DC=cn,DC=bleum,DC=com"
manager-password="({1})" />
-->
<beans:bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<beans:constructor-arg
value="ldap://cn.bleum.com:389/OU=Bleum,DC=cn,DC=bleum,DC=com" />
<beans:property name="userDn"
value="CN=Vincent Meng,OU=JavaBench,OU=Development,OU=Bleum,DC=cn,DC=bleum,DC=com" />
<beans:property name="password" value="BLpla,37410" />
</beans:bean>
<beans:bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<beans:constructor-arg index="0" value="" />
<beans:constructor-arg index="1" value="(CN={0})" />
<beans:constructor-arg index="2" ref="contextSource" />
<beans:property name="searchSubtree" value="true" />
</beans:bean>
<beans:bean id="ldapAuthProvider"
class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
<custom-authentication-provider />
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
<beans:constructor-arg ref="contextSource" />
<beans:property name="userSearch" ref="userSearch" />
</beans:bean>
</beans:constructor-arg>
<beans:constructor-arg>
<beans:bean
class="com.bleum.javateam.skilldb.security.service.AuthoritiesPopulator">
<beans:constructor-arg ref="userServiceImpl" />
</beans:bean>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="anonymousAuthenticationProvider"
class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider">
<beans:property name="key" value="anonymous" />
</beans:bean>
<beans:bean id="authenticationManager"
class="org.springframework.security.providers.ProviderManager">
<beans:property name="providers">
<beans:list>
<beans:ref local="ldapAuthProvider" />
<beans:ref local="anonymousAuthenticationProvider" />
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="authenticationProcessingFilter"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationFailureUrl" value="/login.jsp?error=true" />
<beans:property name="defaultTargetUrl" value="/profile.html" />
<beans:property name="filterProcessesUrl" value="/j_spring_security_check" />
</beans:bean>
<beans:bean id="securityContextHolderAwareRequestFilter"
class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter" />
<beans:bean id="anonymousProcessingFilter"
class="com.bleum.javateam.skilldb.security.service.CustomizeAnonymousProcessingFilter">
<!--
<beans:property name="key" value="anonymous"/> <beans:property
name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
-->
<custom-filter before="ANONYMOUS_FILTER" />
<beans:property name="userAttribute" value="anonymousUser,ROLE_COMMON_USER" />
<beans:property name="key" value="springsecurity" />
</beans:bean>
<beans:bean id="exceptionTranslationFilter"
class="org.springframework.security.ui.ExceptionTranslationFilter">
<beans:property name="authenticationEntryPoint">
<beans:bean
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp" />
<beans:property name="forceHttps" value="false" />
</beans:bean>
</beans:property>
<beans:property name="accessDeniedHandler">
<beans:bean class="org.springframework.security.ui.AccessDeniedHandlerImpl">
<beans:property name="errorPage" value="/accessDenied.html" />
</beans:bean>
</beans:property>
</beans:bean>
<beans:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName"
value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<beans:property name="url"
value="jdbc:sqlserver://192.168.0.71:1433;DatabaseName=skilldb" />
<beans:property name="username" value="root" />
<beans:property name="password" value="javateam2010!" />
</beans:bean>
<beans:bean id="filterInvocationDefinitionSource"
class="com.bleum.javateam.skilldb.security.service.JdbcFilterInvocationDefinitionSourceFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="resourceQuery"
value="
select re.res_value,r.role_name
from role r
join role_resource rr
on r.id=rr.roleId
join resource re
on re.ID=rr.resourceId
order by re.res_priority
" />
</beans:bean>
<beans:bean id="accessDecisionManager"
class="com.bleum.javateam.skilldb.security.service.DecisionManager" />
<beans:bean id="filterSecurityInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="accessDecisionManager" ref="accessDecisionManager" />
<!--
<beans:bean
class="org.springframework.security.vote.AffirmativeBased">
<beans:property name="allowIfAllAbstainDecisions" value="false" />
<beans:property name="decisionVoters"> <beans:list> <beans:bean
class="org.springframework.security.vote.RoleVoter" > <beans:property
name="rolePrefix" value=""/> </beans:bean> <beans:bean
class="org.springframework.security.vote.AuthenticatedVoter" />
</beans:list> </beans:property> </beans:bean>
</beans:property>
-->
<beans:property name="objectDefinitionSource" ref="filterInvocationDefinitionSource" />
</beans:bean>
</beans:beans>
相應的實現類(此類借鑑他人的方法):
public class JdbcFilterInvocationDefinitionSourceFactoryBean extends
JdbcDaoSupport implements FactoryBean {
private String resourceQuery;
public boolean isSingleton() {
return true;
}
public Class getObjectType() {
return FilterInvocationDefinitionSource.class;
}
public Object getObject() {
return new DefaultFilterInvocationDefinitionSource(
this.getUrlMatcher(), this.buildRequestMap());
}
protected Map<String, String> findResources() {
ResourceMapping resourceMapping = new ResourceMapping(getDataSource(),
resourceQuery);
Map<String, String> resourceMap = new LinkedHashMap<String, String>();
for (Resource resource : (List<Resource>) resourceMapping.execute()) {
String url = resource.getUrl();
String role = resource.getRole();
if (resourceMap.containsKey(url)) {
String value = resourceMap.get(url);
resourceMap.put(url, value + "," + role);
} else {
resourceMap.put(url, role);
}
}
return resourceMap;
}
protected LinkedHashMap<RequestKey, ConfigAttributeDefinition> buildRequestMap() {
LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap = null;
requestMap = new LinkedHashMap<RequestKey, ConfigAttributeDefinition>();
ConfigAttributeEditor editor = new ConfigAttributeEditor();
Map<String, String> resourceMap = this.findResources();
for (Map.Entry<String, String> entry : resourceMap.entrySet()) {
RequestKey key = new RequestKey(entry.getKey(), null);
editor.setAsText(entry.getValue());
requestMap.put(key, (ConfigAttributeDefinition) editor.getValue());
}
return requestMap;
}
protected UrlMatcher getUrlMatcher() {
return new AntUrlPathMatcher();
}
public void setResourceQuery(String resourceQuery) {
this.resourceQuery = resourceQuery;
}
private class Resource {
private String url;
private String role;
public Resource(String url, String role) {
this.url = url;
this.role = role;
}
public String getUrl() {
return url;
}
public String getRole() {
return role;
}
}
private class ResourceMapping extends MappingSqlQuery {
protected ResourceMapping(DataSource dataSource, String resourceQuery) {
super(dataSource, resourceQuery);
compile();
}
protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
String url = rs.getString(1);
String role = rs.getString(2);
Resource resource = new Resource(url, role);
return resource;
}
}