5 Replies Latest reply on Nov 10, 2009 2:52 PM by hardaur

    Current Jasig CAS Integration

    hardaur

      I'm being directed to integrate a seam application with other systems that are authenticating through the Ja-Sig CAS SSO system.  I'm looking at Jboss 4.2, Seam 2.1.x, and CAS client 3.1.6.  All I'm finding is ANCIENT information on doing this integration (not much, if anything, newer than 2007).


      The seam application currently uses the current seam 2.x identity system so I've got to actually do a migration.  Everything I'm seeing obviously uses the older seam authentication tools, I'd rather stay current if I can.


      Does anybody have any pointers to anything more current or other information that may provide a bit of a leg up.  This is definitely out of my comfort zone so any help is greatly appreciated. 


      Thanks!
      Gerald

        • 1. Re: Current Jasig CAS Integration
          sebbaweb

          I have the same problem. I'm using:
          JBOSS 5.0 / Seam 2.1.1 / CAS Cliente 3.1.7
          I just find the same anciente information from two thousand and late talking about the integration.


          The mais deal is to build the filters (web.xml) to login and logout at CAS, and make this login/logout to take effect in SEAM identity/credentials system.

          • 2. Re: Current Jasig CAS Integration
            hardaur

            It sounds like you're pretty on top of it, but if you end up stuck, let me know and I'll show you some code.  I've had it up and running in production for a while now.


            Gerald

            • 3. Re: Current Jasig CAS Integration
              trind

              I got problem with CAS, and i would love to see the code if possible.




              //Joachim

              • 4. Re: Current Jasig CAS Integration
                ohughes

                Hi Gerald,


                Any chance of posting the configuration required to get CAS and SEAM working together?


                Thanks,
                Osian

                • 5. Re: Current Jasig CAS Integration
                  hardaur

                  Well, it's been a while, but I'll give it a shot.  Also, though it works pretty much as expected, I am going to be ripping it all out and going a different direction.  I'm still not happy in my context (which isn't exactly what CAS was designed for).


                  In web.xml (note:  this is a dev config so localhost in some places authenticating against production CAS):


                  <filter>
                          <filter-name>CAS Authentication Filter</filter-name>
                          <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
                          <init-param>
                              <param-name>casServerLoginUrl</param-name>
                              <param-value>https://www.mydomain.com/cas/login</param-value>
                          </init-param>
                          <init-param>
                              <param-name>service</param-name>
                              <param-value>http://localhost:8080/myApp/home.seam</param-value>
                          </init-param>
                      </filter>
                  
                      <filter>
                          <filter-name>CAS Validation Filter</filter-name>
                          <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
                          <init-param>
                              <param-name>casServerUrlPrefix</param-name>
                              <param-value>https://cas.mydomain.org:8443/cas</param-value>
                          </init-param>
                          <init-param>
                              <param-name>service</param-name>
                              <param-value>http://localhost:8080/myApp/app/home.seam</param-value>
                          </init-param>
                      </filter>
                  
                      <filter>
                          <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
                          <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
                      </filter>



                  In components.xml:


                  <!-- Disabling seam identity-filter so that I can get the principal information from the request (per CAS) -->
                      <web:identity-filter disabled="true"/>
                      <!--   <security:identity authenticate-method="#{casAuthenticator.authenticate()}" remember-me="false"/>-->



                  And CustomIdentity.java:


                  package com.mydomain.myapp.session.security;
                  
                  import com.mydomain.myapp.entity.UserAccount;
                  import org.jboss.seam.ScopeType;
                  import org.jboss.seam.annotations.*;
                  import static org.jboss.seam.annotations.Install.APPLICATION;
                  import org.jboss.seam.annotations.intercept.BypassInterceptors;
                  import org.jboss.seam.contexts.Contexts;
                  import org.jboss.seam.core.Events;
                  import org.jboss.seam.core.Expressions;
                  import org.jboss.seam.core.Expressions.ValueExpression;
                  import org.jboss.seam.log.LogProvider;
                  import org.jboss.seam.log.Logging;
                  import org.jboss.seam.security.Credentials;
                  import org.jboss.seam.security.Identity;
                  import org.jboss.seam.security.management.IdentityManager;
                  
                  import javax.faces.context.FacesContext;
                  import javax.persistence.EntityManager;
                  import java.security.Principal;
                  
                  @Name("org.jboss.seam.security.identity")
                  @Scope(ScopeType.SESSION)
                  @Install(precedence = APPLICATION)
                  @BypassInterceptors
                  @Startup
                  public class CustomIdentity extends Identity {
                      public static final String AUTHENTICATED_USER = "org.jboss.seam.security.management.authenticatedUser";
                      public static final String EVENT_USER_AUTHENTICATED = "org.jboss.seam.security.management.userAuthenticated";
                      private static final String SILENT_LOGIN = "org.jboss.seam.security.silentLogin";
                  
                      @In(create = true)
                      Credentials credentials;
                  
                      private ValueExpression<EntityManager> entityManager;
                  
                      private static final LogProvider log = Logging.getLogProvider(CustomIdentity.class);
                  
                      public void initEntityManager() {
                          if (entityManager == null) {
                              entityManager = Expressions.instance().createValueExpression("#{entityManager}", EntityManager.class);
                          }
                      }
                  
                      public EntityManager lookupEntityManager() {
                          return entityManager.getValue();
                      }
                  
                      @Override
                      public String login() {
                          initEntityManager();
                          System.out.println("Starting authentication");
                  
                          if (super.isLoggedIn()) {
                              // If authentication has already occurred during this request via a silent login,
                              // and login() is explicitly called then we still want to raise the LOGIN_SUCCESSFUL event,
                              // and then return.
                              if (Contexts.isEventContextActive() && Contexts.getEventContext().isSet(SILENT_LOGIN)) {
                                  if (Events.exists()) Events.instance().raiseEvent(EVENT_LOGIN_SUCCESSFUL);
                                  return "loggedIn";
                              }
                  
                              if (Events.exists()) Events.instance().raiseEvent(EVENT_ALREADY_LOGGED_IN);
                              return "loggedIn";
                          }
                  
                          preAuthenticate();
                  
                          Principal casPrincipal = getCASPrincipal();
                  
                          if (casPrincipal.getName() != null) {
                              String username = casPrincipal.getName();
                  
                              System.out.println("Found CAS principal for " + username + ": authenticated");
                  
                              acceptExternallyAuthenticatedPrincipal(casPrincipal);
                  
                              UserAccount userAccount = (UserAccount) lookupEntityManager().createQuery("from UserAccount where username = :username")
                                      .setParameter("username", username)
                                      .getSingleResult();
                  
                              System.out.println("userAccount for " + username + " loaded");
                  
                              // Ok, we're authenticated from CAS, let's load up the roles
                              for (String role : IdentityManager.instance().getImpliedRoles(username)) {
                                  System.out.println("Adding role \"" + role + "\" to " + username);
                                  addRole(role);
                              }
                  
                              if (Events.exists()) {
                                  if (Contexts.isEventContextActive()) {
                                      Contexts.getEventContext().set(AUTHENTICATED_USER, userAccount);
                                  }
                  
                                  Events.instance().raiseEvent(EVENT_USER_AUTHENTICATED, userAccount);
                              }
                  
                              postAuthenticate();
                  
                              return "loggedIn";
                  
                          }
                  
                          return null;
                      }
                  
                      private Principal getCASPrincipal() {
                          return (Principal) FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
                      }
                  
                      @Override
                      public boolean isLoggedIn() {
                          if (!super.isLoggedIn() && getCASPrincipal() != null) {
                              login();
                          }
                  
                          return super.isLoggedIn();
                      }
                  }



                  Hope that helps you guys at least a little.  If you do learn something more, please follow up on this thread and enlighten others.


                  Thanks!


                  Gerald