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

ant*_*980 5 websphere spring-security

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

  1. 如果这些过滤器中的任何一个都找到了用户名-我想对照我的用户数据库检查该用户名,并根据我在数据库中看到的内容分配角色。(我有一个AuthenticationUserDetailsS​​ervice的实现,该实现为我完成。)
  2. 如果不是,请向用户显示登录页面。根据我的用户数据库检查他们在表单中输入的凭据。

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

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

我的猜测是这些事情之一正在发生:

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

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

顺便说一句,使用'customUserDetailsS​​ervice'的默认身份验证提供程序也不起作用。同样,我可以告诉您,因为日志中没有'customUserDetailsS​​ervice'的输出。

您能建议这里出现什么问题吗?如果不是解决方案,那么将对如何解决此问题提出建议。

ant*_*980 5

好的,我想通了。问题是,即使我在 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>
Run Code Online (Sandbox Code Playgroud)

这会诱使 Websphere 在请求中填写用户主体信息。

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