Here is what I want to achieve:
I am using Websphere and I want to rely on the container to do the authentication (using Kerberos+SPNEGO). When it come to Spring Security, I want to rely on the pre-authentication, and use LDAP to retrieve user details (roles etc) for authorization checking.
Here is the part of Spring app context config I have (tried to only include related parts)
<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>
It mostly worked, I can see correct user name and role coming in for my custom UserDetailsMapper
(com.foo.MyUserDetailsMapper) which comes from LDAP, and inside that I am returning a new UserDetails
with updated roles.
The problem is, in my controller, when I tried to do
SecurityContextHolder.getContext().getAuthentication()
It is returning null. (For which works before I change to pre-authentication)
Is there anything I missed?
Found the problem. Sorry that is mostly because of my own implementation fault which is not visible in the question itself.
My custom UserDetails
impl is incorrectly having getEnabled()
returning false
. In LdapAuthenticationProvider
, it is working fine as there is no checking on the user status.
However, in PreAuthenticatedAuthenticationProvider
, by default there is a UserDetailsChecker
which checks the status of user, for which getEnabled()
returning false
will cause the user details checker to fail silently, and causing authentication not populated to SecurityContext
(i.e. treating that account as not authenticated)
Although it is mostly my implementation issue, I think still worth leaving here as a reference for difference of LdapAuthenticationProvider
and PreAuthenticatedAuthenticationProvider
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With