hi Luke
yes I agree the documentation is clear but as I m not familiar with Siteminder I tried to follow same config.
Now it's working on my side with the following config:
- on Tomcat side the port 8080 is disabled, only the AJP13 is enabled, the config is, the tomcatAuthentication attribute is very important here else REMOTE_USER header will not be passed from the fromtal web server to Tomcat. :
HTML Code:
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"
requiredSecret="XXXX" tomcatAuthentication="false"/>
Then on Spring Security side:
HTML Code:
<security:http entry-point-ref="forbiddenAuthEntryPoint">
<security:intercept-url pattern="/**" access="ROLE_USER" />
<security:custom-filter position="PRE_AUTH_FILTER"
ref="myFilter" />
</security:http>
<!-- If the user is not authenticated error 403 -->
<bean id="forbiddenAuthEntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
<!-- rely on a bespoke filter here-->
<bean id="myFilter"
class="com.mysite.impl.BespokeRequestHeaderAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="preauthAuthProvider"
class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper"
class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<!-- rely on ldapUserDetailsService for Granted Authorities-->
<property name="userDetailsService" ref="ldapUserDetailsService" />
</bean>
</property>
</bean>
<!-- ActiveDirectory LDAP config -->
<!-- contextSource -->
<bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://myhost:389/dc=domain,dc=lan" />
<property name="userDn" value="CN=Administrator,CN=Users,DC=domain,DC=lan" />
<property name="password" value="XXXX" />
</bean>
<!-- userSearch -->
<bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value="CN=Users" />
<constructor-arg index="1" value="(sAMAccountName={0})" />
<constructor-arg index="2" ref="contextSource" />
</bean>
<!-- ldapAuthoritiesPopulator -->
<bean id="ldapAuthoritiesPopulator"
class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg index="0" ref="contextSource" />
<constructor-arg index="1" value="OU=myGrantedAuthorities" />
</bean>
<!-- ldapUserDetailsService -->
<bean id="ldapUserDetailsService"
class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg index="0" ref="userSearch" />
<constructor-arg index="1" ref="ldapAuthoritiesPopulator" />
</bean>
<!-- end ActiveDirectory LDAP config -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
ref="preauthAuthProvider" />
</security:authentication-manager>
In the wiring above I rely on the filter myFilter to get akready authenticated users and I rely on the ActiveDirectory LDAP to get the granted authorities.
The filter is defined as:
PHP Code:
public class BespokeRequestHeaderAuthenticationFilter extends RequestHeaderAuthenticationFilter {
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
//remote user shouldn't be null, make sure you have tomcatAuthentication="false" in your AJP13 config in the $TOMCAT_HOME/conf/server.xml
Assert.notNull(request.getRemoteUser(), "The remote user shouldn't be null, make sure you have tomcatAuthentication=\"false\" in your AJP13 config.");
//we split here as the request.getRemoteUser() in Windows has the following pattern DOMAIN\\userLogin and we want to extract the userLogin
String[] remoteUserSplitted = request.getRemoteUser().split("\\\\");
String principal = remoteUserSplitted.length == 2 ? remoteUserSplitted[1] : remoteUserSplitted[0];
logger.info("Request from user:"+principal);
return principal;
}
}