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

Oli*_*ieu 6 authentication spring spring-security

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

  1. 检查是否存在标头参数
  2. 根据是否存在参数,可以重定向到登录页面(如果未经过身份验证),也可以检查基本身份验证令牌

在这两种情况下,我都有相同的身份验证提供程序,但我不能让它工作.委托入口点工作正常,但我从未进入我的自定义身份验证提供程序...

这是我的安全配置:

    <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" />
Run Code Online (Sandbox Code Playgroud)

任何的想法 ?

Oli*_*ieu 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" />
Run Code Online (Sandbox Code Playgroud)

如你所见,我也添加了一些东西.

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

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

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

当PreAuth使用我的SSO服务时,BasicAuth和LoginURLAuth使用相同的AuthenticationProvider.

希望它可以帮助别人!