如何使用J2eePreAuthenticatedProcessingFilter和自定义身份验证提供程序?

时间:2012-03-22 22:07:43

标签: spring-security websphere

我希望我的Spring应用程序尝试两种预身份验证方法( Siteminder Java EE容器身份验证)。

  1. 如果这些过滤器中的任何一个找到用户名 - 我想根据我的用户数据库检查该用户名,并根据我在数据库中看到的内容分配角色。 (我有一个AuthenticationUserDetailsS​​ervice的实现,它为我做了。)
  2. 如果不是 - 向用户显示登录页面。根据我的用户数据库检查他们在表单中输入的凭据。
  3. Siteminder集成正在运行。登录表单也正常工作。 我的问题在于Java EE预身份验证。它永远不会开始。

    我的applicationContext-security.xml:

    <!-- HTTP security configurations -->
    <sec:http auto-config="true" use-expressions="true">
        <sec:form-login login-processing-url="/resources/j_spring_security_check" always-use-default-target="true" default-target-url="/" login-page="/login"
            authentication-failure-url="/login?login_error=t" />
        <sec:logout logout-url="/resources/j_spring_security_logout" />
        <sec:access-denied-handler error-page="/accessDenied" />
        <sec:remember-me user-service-ref="customUserDetailsService" token-validity-seconds="86400" key="OptiVLM-VaultBalance" />
        <sec:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter"/>
        <sec:custom-filter after="PRE_AUTH_FILTER" ref="jeePreAuthenticatedFilter"/>
    
        <!-- various intercept-url elements here, skipped for brevity -->
    </sec:http>
    
    <!-- Authentication Manager -->
    <sec:authentication-manager alias="authenticationManager">
        <!-- J2EE container pre-authentication or Siteminder -->
        <sec:authentication-provider ref="customPreAuthenticatedAuthenticationProvider" />
        <!-- Default provider -->
        <sec:authentication-provider user-service-ref="customUserDetailsService" />
    </sec:authentication-manager>
    
    <!-- Siteminder pre-authentication -->
    <bean id="siteminderFilter" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
        <property name="principalRequestHeader" value="SM_USER" />
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="exceptionIfHeaderMissing" value="false" />
    </bean>
    
    <!-- J2EE pre-authentication -->
    <bean id="jeePreAuthenticatedFilter" class="org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager" />
    </bean>
    
    <!-- Custom pre-authentication provider -->
    <bean id="customPreAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <property name="preAuthenticatedUserDetailsService" ref="customAuthenticationUserDetailsService" />
    </bean>
    

    我在Websphere中启用了Java 2安全性,并以“admin5”身份登录。 (我的用户数据库中有一个用户名。)但是当我访问应用程序时,从来没有调用'customAuthenticationUserDetailsS​​ervice'bean来验证用户名。我知道这一点,因为'customAuthenticationUserDetailsS​​ervice'进行了大量的日志记录,清楚地显示了它正在做什么。当我使用Siteminder预身份验证 - 'customAuthenticationUserDetailsS​​ervice'工作正常时,我在日志中得到一些跟踪输出。但不适用于J2EE身份验证......

    我的猜测是其中一件事正在发生:

    a)Java EE预身份验证筛选器未找到用户名,因此它从不调用身份验证管理器

    b)Java EE预身份验证筛选器工作正常,但我的自定义身份验证提供程序由于某种原因从未被身份验证管理器调用

    顺便说一下,使用'customUserDetailsS​​ervice'的默认身份验证提供程序也没有启动。我再说一遍,因为日志中没有'customUserDetailsS​​ervice'的输出。

    你能告诉我这里可能出现什么问题吗?如果不是解决方案,那么建议如何处理这个问题将非常感激。

1 个答案:

答案 0 :(得分:3)

好的,我想出来了。问题是即使我在Websphere中进行了J2EE安全设置并且经过身份验证,我的web.xml包含无安全约束。因此,Websphere没有为我的请求提供主体。这显然是一个故意的特征。如果您没有访问受保护的URL,则不需要预身份验证信息。

为了解决这个问题,我在我的web.xml中添加了一个安全约束,允许所有用户访问资源。实际上,资源没有得到保障,但仍然存在 - 现在有一个限制。

就是这样:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>All areas</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>*</role-name>
        </auth-constraint>
</security-constraint>

这会欺骗Websphere填写请求中的用户主体信息。

感谢@Ralph对此问题的评论:request.getUserPrincipal() got null