Spring Security Experience My project

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章