Page 2 of 2 FirstFirst 12
Results 11 to 16 of 16

Thread: Acegi and SiteMinder

  1. #11
    Join Date
    Nov 2005
    Posts
    1

    Default

    Scott,

    The Siteminder support feature looks interesting. We have been recently trying to integrate Siteminder with the J2EE security model. We want to have HTTP HEADERS produced by Siteminder translated into a proper remote user. We would like to be able to use getRemoteUser, getPrincipal, isUserInRole etc. of HttpServletRequest.

    Can ACEGI be configured so that Siteminder protected web apps have access to getRemoteUser, getPrincipal, isUserInRole etc.?

  2. #12
    Join Date
    Aug 2004
    Location
    Columbus, OH, USA
    Posts
    133

    Default

    Adam, the answer is most likely yes, depending on what you're sending through the Siteminder headers. If it's just a user's ID, you're good to go. If you also need to pass group membership, cost center, email address, etc., then you'll want to extend Acegi's Siteminder filter (as well as your AuthenticationDao implementation) to additionally process those headers. In the end Acegi's Siteminder filter doesn't do anything fancy - it just processes authentication requests from HTTP headers instead of form properties.

  3. #13
    Join Date
    Aug 2004
    Posts
    218

    Question LdapAuthenticationProvider integration with Siteminder

    I realize most of the posts here talk about extending the DaoAuthenticationProvider, but since I am getting my authorization roles from LDAP, can't I just extend the LdapAuthenticationProvider? This way I can just swap out the authentication mechanism from LDAP to Siteminder depending the environment and use the nifty declarative approach the LdapAuthenticationProvider affords.

    However, I have attempted to use Acegi 1.0 Siteminder plug-in together with my extended LdapAuthenticationProvider, but no luck. Any suggestions?

    Code:
    	<bean id="authenticationProcessingFilter" class="com.xxx.xxx.common.security.SiteminderAuthenticationProcessingFilter">
    	<property name="authenticationManager"><ref bean="authenticationManager"/></property>
    	<property name="authenticationFailureUrl"><value>/accessDenied.jsp</value></property>
    	<property name="defaultTargetUrl"><value>/jsp/Hello.jsp</value></property>
    	<property name="filterProcessesUrl"><value>/j_acegi_security_check</value></property>
    	<property name="siteminderUsernameHeaderKey"><value>SM_USER</value></property>
    	<property name="siteminderPasswordHeaderKey"><value>SM_USER</value></property>
    	</bean>
    ...
    	<bean id="ldapAuthProvider"
    		class="com.xxx.xxx.common.security.SiteminderLdapAuthenticationProvider">
    		<constructor-arg>
    			<bean
    				class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
    				<constructor-arg>
    					<ref local="initialDirContextFactory"/>
    				</constructor-arg>
    				<property name="userDnPatterns">
    					<list>
    						<value>uid={0},ou=people</value>
    					</list>
    				</property>
    			</bean>
    		</constructor-arg>
    		<constructor-arg>
    			<bean
    				class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
    				<constructor-arg>
    					<ref local="initialDirContextFactory"/>
    				</constructor-arg>
    				<constructor-arg>
    					<value>ou=dl</value>
    				</constructor-arg>
    				<property name="groupRoleAttribute">
    					<value>cn</value>
    				</property>
    			</bean>
    		</constructor-arg>
    	</bean>
    Here's my simple code for the provider for userID/password equality as per the docs, since Siteminder already does authentication (just need LDAP for querying roles for authorization):

    Code:
    public class SiteminderLdapAuthenticationProvider extends
            LdapAuthenticationProvider {
    
        public SiteminderLdapAuthenticationProvider(LdapAuthenticator arg0,
                LdapAuthoritiesPopulator arg1) {
            super(arg0, arg1);
        }
    
        protected final void additionalAuthenticationChecks(
                final UserDetails userDetails,
                final UsernamePasswordAuthenticationToken authentication)
                throws AuthenticationException {
            // Since siteminder does authentication, simply check that
            // the userid and password credentials match form siteminder.
            if (!userDetails.getUsername().equalsIgnoreCase(
                    (String) authentication.getCredentials())) {
                throw new AuthenticationServiceException(
                        "UserName and Password do not match.");
            }
    
        }
    
    }
    Thanks in advance,

  4. #14
    Join Date
    Dec 2004
    Posts
    11

    Default

    The doc regarding SiteminderAuthenticationProcessingFilter meant that you have to provide an AuthentificationProvider which does the check (userID=password) in the authenticate() method.
    This method delegates to retrieveUser() from class AbstractUserDetailsAuthenticationProvider, thus from class LdapAuthenticationProvider.
    You thus should redefine retrieveUser() instead of additionalAuthenticationChecks(). In retrieveUser(), you could simply ignore the authentication call and just invoke:

    return createUserDetails(ldapUser, username, password);

    The password may actually be anything.

    Cheers,
    -- Savrak

  5. #15
    Join Date
    Aug 2004
    Posts
    218

    Default

    Thanks Savrak, but according to the javadocs, it shouldn't matter. It states: "Most of the time subclasses will not perform credentials inspection in this method, instead performing it in AbstractUserDetailsAuthenticationProvider.addition alAuthenticationChecks(UserDetails, UsernamePasswordAuthenticationToken) so that code related to credentials validation need not be duplicated across two methods."

    Also, I won't have an appropriate value to insert for the first parameter of that method, as it returns NullPointerException if I try the way you prescribed without a populated LdapUserDetails. This is because there is no way for me to get the LdapUserDetails without calling the authenticate method. But if I do that, authentication will fail because I don't have the password.

    The only thing I can think is to do an LDAP search on the username by injecting my "usersearch" bean I have in the context into the SiteminderLdapAuthenticationProvider class. Then I can search and it will work, but is this the best approach?

    Thanks,
    Last edited by Loumeister; Jun 13th, 2006 at 01:36 PM.

  6. #16
    Join Date
    Dec 2004
    Posts
    11

    Default

    ... I indeed missed LdapUserDetails. Then I would suggest the following approach:
    - redefine / extend BindAuthenticator. In its authenticate() method, ignore the bind call.
    - inject this Authenticator to LdapAuthenticationProvider. You don't have to implement an additional version of this class.

Similar Threads

  1. Replies: 1
    Last Post: Oct 10th, 2005, 05:23 PM
  2. Replies: 7
    Last Post: Apr 29th, 2005, 03:57 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •