Spring Security + LDAP中的预身份验证

Adr*_*hum 7 java authentication spring spring-security

这是我想要实现的目标:

我正在使用Websphere,我想依靠容器来进行身份验证(使用Kerberos + SPNEGO).当涉及到Spring Security时,我希望依赖于预身份验证,并使用LDAP来检索用户详细信息(角色等)以进行授权检查.

这是我有的Spring应用程序上下文配置的一部分(试图只包括相关部分)

<s:global-method-security secured-annotations="enabled" pre-post-annotations="enabled" proxy-target-class="true" />

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <s:filter-chain-map path-type="ant">
        <s:filter-chain pattern="/**"
            filters="securityContextPersistenceFilter,preAuthenticatedFilter" />
    </s:filter-chain-map>
</bean>


<s:http use-expressions="true" create-session="stateless" auto-config="true">
<!--
    <s:http-basic />
-->
</s:http>

<bean id="securityContextPersistenceFilter" 
        class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
    <property name='securityContextRepository'>
        <bean class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
            <property name='allowSessionCreation' value='true' />
        </bean>
    </property>
</bean>


<bean id="preAuthenticatedFilter"
        class="org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter">
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

<s:authentication-manager alias="authenticationManager">
    <s:authentication-provider ref="preAuthenticatedAuthenticationProvider"   />
</s:authentication-manager>

<bean id="preAuthenticatedAuthenticationProvider" 
        class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    <property name="preAuthenticatedUserDetailsService" >
        <bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper" >
            <property name="userDetailsService" ref="userDetailsService" />
        </bean>
    </property>
</bean>


<bean id="userDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService" >
    <constructor-arg index="0" ref="ldapUserSearch"/>
    <constructor-arg index="1" ref="ldapAuthoritiesPopulator"/>
    <property name="userDetailsMapper" >
        <bean class="com.foo.MyUserDetailsMapper" />
    </property>
</bean>

<bean id="ldapContextSource"
    class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <!-- some setting skipped here -->
</bean>

<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
    <!-- some setting skipped here -->
</bean>

<bean id="ldapAuthoritiesPopulator"
    class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
    <!-- some setting skipped here -->
</bean>

<bean id="ldapTemplate" class="org.springframework.ldap.core.simple.SimpleLdapTemplate">
    <constructor-arg ref="ldapContextSource" />
</bean>
Run Code Online (Sandbox Code Playgroud)

它主要工作,我可以看到正确的用户名和角色来自我的自定义UserDetailsMapper(com.foo.MyUserDetailsMapper)来自LDAP,并在里面,我返回一个新UserDetails的更新角色.

问题是,在我的控制器中,当我尝试做的时候

SecurityContextHolder.getContext().getAuthentication()
Run Code Online (Sandbox Code Playgroud)

它返回null.(在我更改为预认证之前有效)

我错过了什么吗?

Adr*_*hum 7

发现了问题.抱歉,这主要是因为我自己的实现错误,这在问题本身中是看不到的.

我的自定义UserDetailsimpl错误地getEnabled()返回false.在LdapAuthenticationProvider,它正常工作,因为没有检查用户状态.

但是,在PreAuthenticatedAuthenticationProvider默认情况下,有一个UserDetailsChecker检查用户的状态,getEnabled()返回false将导致用户详细信息检查程序无提示失败,并导致身份验证未填充SecurityContext(即将该帐户视为未经过身份验证)

虽然这主要是我的实施问题,但我认为仍然值得留在这里作为LdapAuthenticationProvider和和的差异的参考PreAuthenticatedAuthenticationProvider