Custom Spring 3.0安全过滤器,多个EntryPoints,AuthenticationProvider

时间:2013-02-12 09:59:46

标签: spring authentication spring-security

我需要我的安全性具有以下逻辑:

  1. 检查是否存在标头参数
  2. 根据是否存在参数,可以重定向到登录页面(如果未经过身份验证),也可以检查基本身份验证令牌
  3. 在这两种情况下,我都拥有相同的身份验证提供程序,但我无法使用它。 委托入口点工作正常,但我从未进入我的自定义身份验证提供程序...

    这是我的安全配置:

        <security:global-method-security
        secured-annotations="enabled" />
    
    <security:http entry-point-ref="delegatingAuthenticationEntryPoint"
        use-expressions="true" auto-config="false">
        <!-- <security:custom-filter position="FORM_LOGIN_FILTER" -->
        <!-- ref="usernamePasswordAuthenticationFilter" /> -->
        <!-- <security:custom-filter position="BASIC_AUTH_FILTER" -->
        <!-- ref="basicAuthenticationFilter" /> -->
        <security:intercept-url pattern="/login*"
            filters="none" />
        <security:intercept-url pattern="/portimaLogin*"
            filters="none" />
        <security:intercept-url pattern="/**"
            access="isAuthenticated()" />
    </security:http>
    
    <bean id="delegatingAuthenticationEntryPoint"
        class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
        <constructor-arg>
            <map>
                <entry key="hasHeader('portima','true')" value-ref="PortimaLoginUrlAuthenticationEntryPoint" />
            </map>
        </constructor-arg>
        <property name="defaultEntryPoint" ref="authenticationEntryPoint" />
    </bean>
    
    <bean id="usernamePasswordAuthenticationFilter"
        class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
    </bean>
    
    <bean id="basicAuthenticationFilter"
        class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
    </bean>
    
    <bean id="PortimaLoginUrlAuthenticationEntryPoint"
        class="be.ap.common.security.spring.PortimaLoginUrlAuthenticationEntryPoint">
        <property name="loginFormUrl" value="${portima.login.page}" />
    </bean>
    
    <bean id="authenticationEntryPoint"
        class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
        <property name="realmName" value="AP" />
    </bean>
    
    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider
            ref="authenticationProvider" />
    </security:authentication-manager>
    
    <bean id="authenticationProvider" class="be.ap.common.security.spring.APAuthenticationProvider" />
    
    <bean id="userDetailsService" class="be.ap.common.security.spring.APUserDetailsService" />
    

    有什么想法吗?

1 个答案:

答案 0 :(得分:12)

我终于有了它的工作。

这是我的上下文文件:

    <security:http entry-point-ref="delegatingAuthenticationEntryPoint"
    use-expressions="true">
    <security:custom-filter position="PRE_AUTH_FILTER"
        ref="preAuthenticationFilter" />
    <security:custom-filter position="FORM_LOGIN_FILTER"
        ref="usernamePasswordAuthenticationFilter" />
    <security:custom-filter position="BASIC_AUTH_FILTER"
        ref="basicAuthenticationFilter" />
    <security:intercept-url pattern="/login*"
        filters="none" />
    <security:intercept-url pattern="/portimaLogin*"
        filters="none" />
    <security:intercept-url pattern="/accessDenied*"
        filters="none" />
    <security:intercept-url pattern="/**"
        access="isAuthenticated()" />
    <security:access-denied-handler ref="accessDeniedHandler" />
</security:http>

<!-- Spring Security Custom Filters -->

<bean id="usernamePasswordAuthenticationFilter"
    class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManager" />
    <property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
</bean>

<bean id="basicAuthenticationFilter"
    class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManager" />
    <property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
</bean>

<bean id="preAuthenticationFilter" class="be.ap.common.security.spring.APPreAuthenticationFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<!-- Spring Security Custom EntryPoint -->

<bean id="delegatingAuthenticationEntryPoint"
    class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
    <constructor-arg>
        <map>
            <entry key="hasHeader('portima','true')" value-ref="PortimaLoginUrlAuthenticationEntryPoint" />
        </map>
    </constructor-arg>
    <property name="defaultEntryPoint" ref="authenticationEntryPoint" />
</bean>

<bean id="PortimaLoginUrlAuthenticationEntryPoint"
    class="be.ap.common.security.spring.PortimaLoginUrlAuthenticationEntryPoint">
    <property name="loginFormUrl" value="${portima.login.page}" />
</bean>

<bean id="authenticationEntryPoint"
    class="be.ap.common.security.spring.APBasicAuthenticationEntryPoint">
    <property name="realmName" value="AP" />
</bean>
<bean id="accessDeniedHandler"
    class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
    <property name="errorPage" value="/accessDenied" />
</bean>

<bean id="authenticationFailureHandler"
    class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
    <property name="exceptionMappings">
        <props>
            <prop
                key="org.springframework.security.authentication.BadCredentialsException">
                /accessDenied
            </prop>
            <prop
                key="org.springframework.security.authentication.CredentialsExpiredException">
                /accessDenied
            </prop>
            <prop key="org.springframework.security.authentication.LockedException">
                /accessDenied
            </prop>
            <prop
                key="org.springframework.security.authentication.DisabledException">
                /accessDenied
            </prop>
        </props>
    </property>
</bean>

<!-- Spring Security Authentication Manager -->

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider
        ref="authenticationProvider" />
</security:authentication-manager>

<bean id="authenticationProvider" class="be.ap.common.security.spring.APAuthenticationProvider" />

<bean id="userDetailsService" class="be.ap.common.security.spring.APUserDetailsService" />

<!-- for Mock -->
<bean id="SSOService" class="be.ap.security.service.SSOServiceMockImpl" />

正如你所看到的,我也添加了一些东西。

要修复它,我会重新启动auto-config属性,取消注释过滤器,并正确定义它们。

对于想要快速了解它的作用的其他人来说,这就是流程:

  1. PRE_AUTH_FILTER将检查类似服务的SSO以预填充身份验证对象(如果已在SSO中进行了身份验证)
  2. delegatingAuthenticationEntryPoint将根据请求标题选择如何进行身份验证
  3. 这两种方式是:
    • 自定义LoginUrlAuthenticationEntryPoint
    • 自定义BasicAuthenticationEntryPoint
  4. 当PreAuth使用我的SSO服务时,

    BasicAuth和LoginURLAuth使用相同的AuthenticationProvider。

    希望它可以帮助别人!