Title: Finally got Siteminder to Integrate /w Acegi Security
 
Scott,
         Please do read me message when you get the chance it is important that we get it right.
If there is a better solution then we should try to find it. The one question that remains in my mind
is this, if authentication is only attempted in the SiteminderAuthenticationProcessingFilter when it
receives a "j_security_check"  and "j_security_check" only gets posed from the login page how
did your Siteminder enabled application get authenticated? From the login page Acegi get
"j_security_check", a username and a password. While from Siteminder Acegi receives only
a username so how can it authenticate without the "j_security_check"?

- Paul

 


From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of [EMAIL PROTECTED]
Sent: Sunday, February 05, 2006 8:58 PM
To: [email protected]
Subject: RE: [Acegisecurity-developer] Finally got Siteminder to Integrate /w Acegi Security

This is great news Paul - big kudos for keeping at it.  I'm swamped this week, but I'll read your message in depth ASAP to see if there's anything we can do to make the Siteminder/Acegi adaptation process easier.
    Scott


From: Garvey, Paul M (GE Commercial Finance) [mailto:[EMAIL PROTECTED]
Sent: Sunday, February 05, 2006 4:28 PM
To: [EMAIL PROTECTED]; [email protected]
Subject: [Acegisecurity-developer] Finally got Siteminder to Integrate /w Acegi Security

All,
     I finally got Siteminder integrated with Acegi in my appfuse 1.9 application. It
is deployed on JBoss 4.0 running on Linux 3.0 and j2sdk1.4.2_06.
Has it turns out I did not have to make much changes. Here is what I had to do:-

1. Create a new filter class that extends SiteminderAuthenticationProcessingFilter.
2. Override the requiresAuthentication() method which is found on the grandparent
    of the SiteminderAuthenticationProcessingFilter class the AbstractProcessingFilter
    class.
    Why did I need to override the requiresAuthentication() method?
    ========================================
    This method normally attempts authentication when it receives a j_security_check
    url from the login page. In the case of Siteminder a j_security_check is never issued
    form a login page so the method is modified to attempt authentication if it receives a
    a j_security_check from the login page or if the getDefaultTargetUrl() is received and
    the user is NOT already authenticated. In this case the getDefaultTargetUrl() is
    /mainMenu.html.

    Method requiresAuthentication() is overridden on new filter class:-
    =============================================

    protected boolean requiresAuthentication(HttpServletRequest request,
        HttpServletResponse response) {
        String uri = request.getRequestURI();
        int pathParamIndex = uri.indexOf(';');

        if (pathParamIndex > 0) {
            // strip everything after the first semi-colon
            uri = uri.substring(0, pathParamIndex);
        }
        //attempt authentication if j_secuity_check is present or if the getDefaultTargetUrl()
        //is present and user is not already authenticated.
        boolean bAuthenticated = false;
        SecurityContext context = (SecurityContext)request.getSession().getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);

        if (context != null) {
           Authentication auth = context.getAuthentication();             
           if (auth != null && auth instanceof UsernamePasswordAuthenticationToken) {
                   UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken)auth;                 

                   bAuthenticated = token.isAuthenticated();
           }
        }  
        //if true is returned then authentication will be attempted.
        boolean bAttemptAuthentication = (uri.endsWith(request.getContextPath() + getFilterProcessesUrl())) ||
                                        ((uri.endsWith(getDefaultTargetUrl()) && !bAuthenticated));
        if (logger.isDebugEnabled()) {
            logger.debug(
                "Authentication attempted for the following URI ==> " + uri + " is " + bAttemptAuthentication);
        }
        return bAttemptAuthentication;
    }


    Original requiresAuthentication()  on the AbstractProcessingFilter class:-
    =============================================

    protected boolean requiresAuthentication(HttpServletRequest request,
        HttpServletResponse response) {
        String uri = request.getRequestURI();
        int pathParamIndex = uri.indexOf(';');

        if (pathParamIndex > 0) {
            // strip everything after the first semi-colon
            uri = uri.substring(0, pathParamIndex);
        }
        return uri.endsWith(request.getContextPath() + filterProcessesUrl);
    }

3. Changes to the application-security.xml:-

   <bean id="authenticationProcessingFilter" class="org.appfuse.webapp.filter.GESiteminderAuthenticationProcessingFilter">

              <property name="authenticationManager" ref="authenticationManager"/>
              <property name="authenticationFailureUrl" value="/login.jsp?error=true"/>
              <property name="defaultTargetUrl" value="/mainMenu.html"/>
              <property name="filterProcessesUrl" value="/j_security_check"/>
              <property name="siteminderUsernameHeaderKey" value="SM_USER"/>
              <property name="siteminderPasswordHeaderKey" value="SM_USER"/>
              <property name="rememberMeServices" ref="rememberMeServices"/>
    </bean>


If there is an easier way to achieving the solution or a question to the approach I took please don't
hesitate to comment.

Thanks,
- Paul

Reply via email to