Author: sohil.shah(a)jboss.com
Date: 2007-05-24 22:37:52 -0400 (Thu, 24 May 2007)
New Revision: 7332
Added:
branches/2_6_CAS_Integration/core/src/resources/portal-server-war/WEB-INF/context.xml
branches/2_6_CAS_Integration/identity/cas/
branches/2_6_CAS_Integration/identity/cas/lib/
branches/2_6_CAS_Integration/identity/cas/lib/cas-server-3.0.7.jar
branches/2_6_CAS_Integration/identity/cas/lib/casclient-lenient.jar
branches/2_6_CAS_Integration/identity/cas/lib/casclient.jar
branches/2_6_CAS_Integration/identity/cas/lib/catalina.jar
branches/2_6_CAS_Integration/identity/cas/lib/spring-2.0.3.jar
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/AuthenticationService.java
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationHandler.java
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationService.java
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationValve.java
Modified:
branches/2_6_CAS_Integration/core/build.xml
branches/2_6_CAS_Integration/core/src/resources/portal-core-sar/META-INF/jboss-service.xml
branches/2_6_CAS_Integration/identity/build.xml
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/IdentityLoginModule.java
Log:
CAS SSO Framework Integration
Modified: branches/2_6_CAS_Integration/core/build.xml
===================================================================
--- branches/2_6_CAS_Integration/core/build.xml 2007-05-24 22:23:32 UTC (rev 7331)
+++ branches/2_6_CAS_Integration/core/build.xml 2007-05-25 02:37:52 UTC (rev 7332)
@@ -341,7 +341,7 @@
<fileset dir="${apache.fileupload.lib}"
includes="commons-fileupload.jar"/>
<fileset dir="${jakarta.io.lib}"
includes="commons-io.jar"/>
<fileset dir="${freemarker.freemarker.lib}"
includes="freemarker.jar"/>
- <fileset dir="${portals.bridges.lib}"
includes="portals-bridges-common.jar"/>
+ <fileset dir="${portals.bridges.lib}"
includes="portals-bridges-common.jar"/>
</copy>
<!--dtd-->
@@ -721,4 +721,40 @@
</junitreport>
</target>
+ <target name="deploy-explode" depends="output,explode">
+ <require file="${jboss.home}/server/${portal.deploy.dir}"/>
+ <copy
todir="${jboss.home}/server/${portal.deploy.dir}/jboss-portal.sar"
overwrite="true">
+ <fileset dir="${build.lib}/jboss-portal-exploded.sar"/>
+ </copy>
+ </target>
+
+ <target name="explode-ha" depends="init">
+ <explode
+ file="${build.lib}/jboss-portal-ha.sar"
+ todir="${build.lib}"
+ name="jboss-portal-ha-exploded.sar"
+ />
+ </target>
+
+ <target name="deploy-ha-explode" description="Deploy high
availability." depends="output-ha,explode-ha">
+ <require file="${jboss.home}/server/${portal-ha.deploy.dir}"/>
+ <copy
todir="${jboss.home}/server/${portal-ha.deploy.dir}/jboss-portal-ha.sar"
overwrite="true">
+ <fileset dir="${build.lib}/jboss-portal-ha-exploded.sar"/>
+ </copy>
+ </target>
+
+ <target name="deploy-cas" depends="deploy-explode">
+ <require file="${jboss.home}/server/${portal.deploy.dir}"/>
+ <delete
file="${jboss.home}/server/${portal.deploy.dir}/jboss-portal.sar/lib/casclient-lenient.jar"/>
+ <copy
todir="${jboss.home}/server/${portal.deploy.dir}/jboss-portal.sar/lib"
overwrite="true">
+ <fileset dir="../identity/cas/lib" includes="casclient.jar"/>
+ </copy>
+ </target>
+ <target name="deploy-cas-lenient" depends="deploy-explode">
+ <require file="${jboss.home}/server/${portal.deploy.dir}"/>
+ <delete
file="${jboss.home}/server/${portal.deploy.dir}/jboss-portal.sar/lib/casclient.jar"/>
+ <copy
todir="${jboss.home}/server/${portal.deploy.dir}/jboss-portal.sar/lib"
overwrite="true">
+ <fileset dir="../identity/cas/lib"
includes="casclient-lenient.jar"/>
+ </copy>
+ </target>
</project>
Modified:
branches/2_6_CAS_Integration/core/src/resources/portal-core-sar/META-INF/jboss-service.xml
===================================================================
---
branches/2_6_CAS_Integration/core/src/resources/portal-core-sar/META-INF/jboss-service.xml 2007-05-24
22:23:32 UTC (rev 7331)
+++
branches/2_6_CAS_Integration/core/src/resources/portal-core-sar/META-INF/jboss-service.xml 2007-05-25
02:37:52 UTC (rev 7332)
@@ -519,6 +519,15 @@
<attribute name="RegisterMBeans">true</attribute>
<attribute
name="ConfigFile">conf/identity/identity-config.xml</attribute>
<attribute
name="DefaultConfigFile">conf/identity/standardidentity-config.xml</attribute>
+ </mbean>
+ <mbean
+ code="org.jboss.portal.identity.auth.CASAuthenticationService"
+ name="portal:service=Module,type=CASAuthenticationService"
+ xmbean-dd=""
+ xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
+ <xmbean/>
+ <depends>portal:service=Module,type=IdentityServiceController</depends>
+ <attribute name="HavingRole"></attribute>
</mbean>
<mbean
Added:
branches/2_6_CAS_Integration/core/src/resources/portal-server-war/WEB-INF/context.xml
===================================================================
--- branches/2_6_CAS_Integration/core/src/resources/portal-server-war/WEB-INF/context.xml
(rev 0)
+++
branches/2_6_CAS_Integration/core/src/resources/portal-server-war/WEB-INF/context.xml 2007-05-25
02:37:52 UTC (rev 7332)
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<Context>
+ <Valve className="org.jboss.portal.identity.auth.CASAuthenticationValve"
+ casLogin="https://localhost/cas/login"
+ casValidate="https://localhost/cas/serviceValidate"
+ casServerName="localhost"
+ authType="FORM"
+ />
+</Context>
Modified: branches/2_6_CAS_Integration/identity/build.xml
===================================================================
--- branches/2_6_CAS_Integration/identity/build.xml 2007-05-24 22:23:32 UTC (rev 7331)
+++ branches/2_6_CAS_Integration/identity/build.xml 2007-05-25 02:37:52 UTC (rev 7332)
@@ -60,7 +60,7 @@
&tools;
&targets;
-
+
<!-- ================================================================== -->
<!-- Initialization -->
<!-- ================================================================== -->
@@ -88,6 +88,17 @@
<!-- Configure thirdparty libraries -->
&libraries;
+
+ <!--TODO: need to add the CAS SSO system dependency to the thirdparty
repository. For now, this is just added to identity/cas/lib -->
+ <property name="yale.cas.root" value="cas"/>
+ <property name="yale.cas.lib"
value="${yale.cas.root}/lib/"/>
+ <path id="yale.cas.classpath">
+ <pathelement path="${yale.cas.lib}/casclient.jar"/>
+ <pathelement path="${yale.cas.lib}/cas-server-3.0.7.jar"/>
+ <pathelement path="${yale.cas.lib}/catalina.jar"/>
+ <pathelement path="${yale.cas.lib}/spring-2.0.3.jar"/>
+ </path>
+
<path id="library.classpath">
<path refid="sun.servlet.classpath"/>
<path refid="jboss.microcontainer.classpath"/>
@@ -100,6 +111,9 @@
<path refid="junit.junit.classpath"/>
<pathelement location="${project.tools}/lib/ant.jar"/>
<!--<path refid="sun.opends.classpath"/>-->
+ <!-- cas integration -->
+ <path refid="sun.servlet.classpath"/>
+ <path refid="yale.cas.classpath"/>
</path>
<path id="javac.classpath">
Added: branches/2_6_CAS_Integration/identity/cas/lib/cas-server-3.0.7.jar
===================================================================
(Binary files differ)
Property changes on: branches/2_6_CAS_Integration/identity/cas/lib/cas-server-3.0.7.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/2_6_CAS_Integration/identity/cas/lib/casclient-lenient.jar
===================================================================
(Binary files differ)
Property changes on: branches/2_6_CAS_Integration/identity/cas/lib/casclient-lenient.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/2_6_CAS_Integration/identity/cas/lib/casclient.jar
===================================================================
(Binary files differ)
Property changes on: branches/2_6_CAS_Integration/identity/cas/lib/casclient.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/2_6_CAS_Integration/identity/cas/lib/catalina.jar
===================================================================
(Binary files differ)
Property changes on: branches/2_6_CAS_Integration/identity/cas/lib/catalina.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/2_6_CAS_Integration/identity/cas/lib/spring-2.0.3.jar
===================================================================
(Binary files differ)
Property changes on: branches/2_6_CAS_Integration/identity/cas/lib/spring-2.0.3.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/AuthenticationService.java
===================================================================
---
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/AuthenticationService.java
(rev 0)
+++
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/AuthenticationService.java 2007-05-25
02:37:52 UTC (rev 7332)
@@ -0,0 +1,33 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.identity.auth;
+
+/*
+ * Created on May 24, 2007
+ *
+ * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
+ */
+public interface AuthenticationService
+{
+ public boolean authenticate(String username,String password);
+}
Added:
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationHandler.java
===================================================================
---
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationHandler.java
(rev 0)
+++
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationHandler.java 2007-05-25
02:37:52 UTC (rev 7332)
@@ -0,0 +1,75 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.identity.auth;
+
+
+//jmx related
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import org.jboss.mx.util.MBeanProxy;
+import org.jboss.mx.util.MBeanServerLocator;
+
+
+import org.jasig.cas.authentication.handler.AuthenticationException;
+import
org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
+import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
+
+
+import org.jboss.portal.identity.auth.AuthenticationService;
+
+/*
+ * Created on May 23, 2007
+ *
+ * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
+ */
+public class CASAuthenticationHandler extends
+AbstractUsernamePasswordAuthenticationHandler
+{
+ /**
+ *
+ */
+ protected boolean authenticateUsernamePasswordInternal(UsernamePasswordCredentials
credentials) throws AuthenticationException
+ {
+ try
+ {
+ boolean status = false;
+
+ String username = credentials.getUsername();
+ String password = credentials.getPassword();
+
+ MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
+ AuthenticationService authService = (AuthenticationService)
+ MBeanProxy.get(AuthenticationService.class,new
ObjectName("portal:service=Module,type=CASAuthenticationService"),mbeanServer);
+
+ //Perform this operation in the context of a UserTransaction
+ status = authService.authenticate(username, password);
+
+ return status;
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ return false;
+ }
+ }
+}
Added:
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationService.java
===================================================================
---
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationService.java
(rev 0)
+++
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationService.java 2007-05-25
02:37:52 UTC (rev 7332)
@@ -0,0 +1,164 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.identity.auth;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.naming.InitialContext;
+
+import org.apache.log4j.Logger;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+
+import org.jboss.portal.identity.Role;
+import org.jboss.portal.identity.UserModule;
+import org.jboss.portal.identity.UserProfileModule;
+import org.jboss.portal.identity.MembershipModule;
+import org.jboss.portal.identity.User;
+
+/*
+ * Created on May 24, 2007
+ *
+ * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
+ */
+public class CASAuthenticationService implements AuthenticationService
+{
+ private static Logger log = Logger.getLogger(CASAuthenticationService.class);
+
+ private UserModule userModule = null;
+ private UserProfileModule profileModule = null;
+ private MembershipModule membershipModule = null;
+ private String havingRole = null;
+
+ /**
+ *
+ *
+ */
+ public void start()
+ {
+ try
+ {
+ InitialContext initialContext = new InitialContext();
+
+ this.userModule =
(UserModule)initialContext.lookup("java:/portal/UserModule");
+ this.profileModule =
(UserProfileModule)initialContext.lookup("java:/portal/UserProfileModule");
+ this.membershipModule =
(MembershipModule)initialContext.lookup("java:/portal/MembershipModule");
+ }
+ catch(Exception e)
+ {
+ log.error(this, e);
+ this.stop();
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ public void stop()
+ {
+ this.userModule = null;
+ this.profileModule = null;
+ this.membershipModule = null;
+ this.havingRole = null;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getHavingRole()
+ {
+ return havingRole;
+ }
+
+ /**
+ *
+ * @param havingRole
+ */
+ public void setHavingRole(String havingRole)
+ {
+ this.havingRole = havingRole;
+ }
+
+ /**
+ *
+ */
+ public boolean authenticate(String username, String password)
+ {
+ try
+ {
+ boolean status = false;
+
+ InitialContext initialContext = new InitialContext();
+ SessionFactory sessionFactory =
(SessionFactory)initialContext.lookup("java:/portal/IdentitySessionFactory");
+ Session session = sessionFactory.openSession();
+ Transaction tx = session.beginTransaction();
+
+ User user = this.userModule.findUserByUserName(username);
+ if(user != null)
+ {
+ //Check and make sure the user account is enabled
+ Boolean enabled = (Boolean)this.profileModule.getProperty(user,
User.INFO_USER_ENABLED);
+ if(enabled != null || enabled.booleanValue())
+ {
+ //Check and make sure user has proper role setup
+ if(this.havingRole != null &&
this.havingRole.trim().length()>0)
+ {
+ boolean hasTheRole = false;
+ Set roles = this.membershipModule.getRoles(user);
+ for (Iterator i = roles.iterator(); i.hasNext();)
+ {
+ Role role = (Role)i.next();
+ if (this.havingRole.equals(role.getName()))
+ {
+ hasTheRole = true;
+ break;
+ }
+ }
+ if (!hasTheRole)
+ {
+ return false;
+ }
+ }
+
+ //Now perform validation
+ status = user.validatePassword(password);
+ }
+ }
+
+ tx.commit();
+ session.close();
+
+ return status;
+ }
+ catch(Exception e)
+ {
+ log.error(this, e);
+ return false;
+ }
+ }
+}
Added:
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationValve.java
===================================================================
---
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationValve.java
(rev 0)
+++
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/CASAuthenticationValve.java 2007-05-25
02:37:52 UTC (rev 7332)
@@ -0,0 +1,425 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2006, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.identity.auth;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.security.Principal;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Session;
+import org.apache.catalina.authenticator.Constants;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.valves.ValveBase;
+
+import edu.yale.its.tp.cas.client.*;
+
+/*
+ * Created on May 23, 2007
+ *
+ * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
+ */
+public class CASAuthenticationValve extends ValveBase
+{
+ /**
+ * The name of the filter initialization parameter the value of which should
+ * be the https: address of the CAS Login servlet. Optional parameter, but
+ * required for successful redirection of unauthenticated requests to
+ * authentication.
+ */
+ public final static String LOGIN_INIT_PARAM =
"edu.yale.its.tp.cas.client.filter.loginUrl";
+
+ /**
+ * The name of the filter initialization parameter the value of which must be
+ * the https: address of the CAS Validate servlet. Must be a CAS 2.0 validate
+ * servlet (CAS 1.0 non-XML won't suffice). Required parameter.
+ */
+ public final static String VALIDATE_INIT_PARAM =
"edu.yale.its.tp.cas.client.filter.validateUrl";
+
+ /**
+ * The name of the filter initialization parameter the value of which must be
+ * the address of the service this filter is filtering. The filter will use
+ * this as the service parameter for CAS login and validation. Either this
+ * parameter or SERVERNAME_INIT_PARAM must be set.
+ */
+ public final static String SERVICE_INIT_PARAM =
"edu.yale.its.tp.cas.client.filter.serviceUrl";
+
+ /**
+ * The name of the filter initialization parameter the vlaue of which must be
+ * the server name, e.g.
www.yale.edu , of the service this filter is
+ * filtering. The filter will construct from this name and the request the
+ * full service parameter for CAS login and validation.
+ */
+ public final static String SERVERNAME_INIT_PARAM =
"edu.yale.its.tp.cas.client.filter.serverName";
+
+ /**
+ * The name of the filter initialization parameter the value of which must be
+ * the String that should be sent as the "renew" parameter on the request
for
+ * login and validation. This should either be "true" or not be set. It is
+ * mutually exclusive with GATEWAY.
+ */
+ public final static String RENEW_INIT_PARAM =
"edu.yale.its.tp.cas.client.filter.renew";
+
+ /**
+ * The name of the filter initialization parameter the value of which must be
+ * a whitespace delimited list of services (ProxyTicketReceptors) authorized
+ * to proxy authentication to the service filtered by this Filter. These must
+ * be https: URLs. This parameter is optional - not setting it results in no
+ * proxy tickets being acceptable.
+ */
+ public final static String AUTHORIZED_PROXY_INIT_PARAM =
"edu.yale.its.tp.cas.client.filter.authorizedProxy";
+
+ /**
+ * The name of the filter initialization parameter the value of which must be
+ * the https: URL to which CAS should send Proxy Granting Tickets when this
+ * filter validates tickets.
+ */
+ public final static String PROXY_CALLBACK_INIT_PARAM =
"edu.yale.its.tp.cas.client.filter.proxyCallbackUrl";
+
+ /**
+ * The name of the filter initialization parameter the value of which
+ * indicates whether this filter should wrap requests to expose the
+ * authenticated username.
+ */
+ public final static String WRAP_REQUESTS_INIT_PARAM =
"edu.yale.its.tp.cas.client.filter.wrapRequest";
+
+ /**
+ * The name of the filter initialization parameter the value of which is the
+ * value the Filter should send for the gateway parameter on the CAS login
+ * request.
+ */
+ public final static String GATEWAY_INIT_PARAM =
"edu.yale.its.tp.cas.client.filter.gateway";
+
+ // Session attributes used by this filter
+
+ /**
+ * <p>
+ * Session attribute in which the username is stored.
+ * </p>
+ */
+ public final static String CAS_FILTER_USER =
"edu.yale.its.tp.cas.client.filter.user";
+
+ /**
+ * Session attribute in which the CASReceipt is stored.
+ */
+ public final static String CAS_FILTER_RECEIPT =
"edu.yale.its.tp.cas.client.filter.receipt";
+
+ // *********************************************************************
+ // Configuration state
+ /** Secure URL whereat CAS offers its login service. */
+ private String casLogin;
+
+ /** Secure URL whereat CAS offers its CAS 2.0 validate service */
+ private String casValidate;
+
+ /** Filtered service URL for use as service parameter to login and validate */
+ private String casServiceUrl;
+
+ /**
+ * Name of server, for use in assembling service URL for use as service
+ * parameter to login and validate.
+ */
+ private String casServerName;
+
+ /**
+ * Secure URL whereto this filter should ask CAS to send Proxy Granting
+ * Tickets.
+ */
+ private String casProxyCallbackUrl;
+
+ /** True if renew parameter should be set on login and validate */
+ private boolean casRenew;
+
+ /** True if this filter should set gateway=true on login redirect */
+ private boolean casGateway = false;
+
+ /**
+ * List of ProxyTicketReceptor URLs of services authorized to proxy to the
+ * path behind this filter.
+ */
+ private List authorizedProxies = new ArrayList();
+
+ private String authType = null;
+
+ public String getCasLogin()
+ {
+ return casLogin;
+ }
+
+ public void setCasLogin(String casLogin)
+ {
+ this.casLogin = casLogin;
+ }
+
+ public String getCasServerName()
+ {
+ return casServerName;
+ }
+
+ public void setCasServerName(String casServerName)
+ {
+ this.casServerName = casServerName;
+ }
+
+ public String getCasValidate()
+ {
+ return casValidate;
+ }
+
+ public void setCasValidate(String casValidate)
+ {
+ this.casValidate = casValidate;
+ }
+
+ public String getAuthType()
+ {
+ return authType;
+ }
+
+ public void setAuthType(String authType)
+ {
+ this.authType = authType;
+ }
+
+ /**
+ *
+ */
+ public void invoke(Request request, Response response) throws IOException,
+ ServletException
+ {
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
+ HttpSession session = httpRequest.getSession();
+ this.casRenew = true; // this value helps with logout...otherwise user
+ // is never able to logout
+
+ String requestURI = request.getRequestURI();
+ if ((requestURI.indexOf("/auth/") != -1
+ || requestURI.indexOf("/authsec/") != -1 || requestURI
+ .indexOf("/sec/") != -1)
+ && request.getParameter("ticket") == null
+ && session.getAttribute(CAS_FILTER_USER) == null)
+ {
+ // perform CAS login by going to the CAS authentication server
+ redirectToCAS((HttpServletRequest) request,
+ (HttpServletResponse) response);
+ return;
+ }
+
+ // perform CAS logout if needed
+ if (request.getParameter("ticket") != null
+ && session.getAttribute(CAS_FILTER_USER) == null)
+ {
+ CASReceipt receipt = null;
+ try
+ {
+ receipt = getAuthenticatedUser(httpRequest);
+ }
+ catch (CASAuthenticationException e)
+ {
+ throw new ServletException(e);
+ }
+
+ if (!isReceiptAcceptable(receipt))
+ {
+ throw new ServletException(
+ "Authentication was technically successful but rejected as a
matter of policy. ["
+ + receipt + "]");
+ }
+
+ session.setAttribute(CAS_FILTER_USER, receipt.getUserName());
+ session.setAttribute(CAS_FILTER_RECEIPT, receipt);
+
+ // perform the portal JAAS authentication
+ String user = receipt.getUserName();
+ request.setAttribute("ssoSuccess", new Boolean(true));
+ Principal principal = ((Context) this.container).getRealm()
+ .authenticate(user, (String) null);
+ if (principal != null)
+ {
+ this.register(request, response, principal, this.authType, user,
+ (String) null);
+ }
+ }
+
+ // continue processing the request
+ this.getNext().invoke(request, response);
+ }
+
+ /**
+ * Register an authenticated Principal and authentication type in our
+ * request, in the current session (if there is one), and with our
+ * SingleSignOn valve, if there is one. Set the appropriate cookie to be
+ * returned.
+ *
+ * @param request
+ * The servlet request we are processing
+ * @param response
+ * The servlet response we are generating
+ * @param principal
+ * The authenticated Principal to be registered
+ * @param authType
+ * The authentication type to be registered
+ * @param username
+ * Username used to authenticate (if any)
+ * @param password
+ * Password used to authenticate (if any)
+ */
+ private void register(Request request, Response response,
+ Principal principal, String authType, String username, String password)
+ {
+ // Cache the authentication information in our request
+ request.setAuthType(authType);
+ request.setUserPrincipal(principal);
+
+ Session session = request.getSessionInternal(false);
+ // Cache the authentication information in our session, if any
+ if (session != null)
+ {
+ session.setAuthType(authType);
+ session.setPrincipal(principal);
+ if (username != null)
+ {
+ session.setNote(Constants.SESS_USERNAME_NOTE, username);
+ }
+ else
+ {
+ session.removeNote(Constants.SESS_USERNAME_NOTE);
+ }
+ if (password != null)
+ {
+ session.setNote(Constants.SESS_PASSWORD_NOTE, password);
+ }
+ else
+ {
+ session.removeNote(Constants.SESS_PASSWORD_NOTE);
+ }
+ }
+ }
+
+ // CAS related utility
+ //
methods---------------------------------------------------------------------------------------------------------
+ /**
+ * Is this receipt acceptable as evidence of authentication by credentials
+ * that would have been acceptable to this path? Current implementation
+ * checks whether from renew and whether proxy was authorized.
+ *
+ * @param receipt
+ * @return true if acceptable, false otherwise
+ */
+ private boolean isReceiptAcceptable(CASReceipt receipt)
+ {
+ if (receipt == null) throw new IllegalArgumentException(
+ "Cannot evaluate a null receipt.");
+ if (this.casRenew && !receipt.isPrimaryAuthentication())
+ {
+ return false;
+ }
+ if (receipt.isProxied())
+ {
+ if (!this.authorizedProxies.contains(receipt.getProxyingService()))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Converts a ticket parameter to a CASReceipt, taking into account an
+ * optionally configured trusted proxy in the tier immediately in front of
+ * us.
+ *
+ * @throws ServletException -
+ * when unable to get service for request
+ * @throws CASAuthenticationException -
+ * on authentication failure
+ */
+ private CASReceipt getAuthenticatedUser(HttpServletRequest request)
+ throws ServletException, CASAuthenticationException
+ {
+ ProxyTicketValidator pv = null;
+
+ pv = new ProxyTicketValidator();
+ pv.setCasValidateUrl(casValidate);
+ pv.setServiceTicket(request.getParameter("ticket"));
+ pv.setService(getService(request));
+ pv.setRenew(Boolean.valueOf(casRenew).booleanValue());
+ if (casProxyCallbackUrl != null)
+ {
+ pv.setProxyCallbackUrl(casProxyCallbackUrl);
+ }
+
+ return CASReceipt.getReceipt(pv);
+ }
+
+ /**
+ * Returns either the configured service or figures it out for the current
+ * request. The returned service is URL-encoded.
+ */
+ private String getService(HttpServletRequest request)
+ throws ServletException
+ {
+ String serviceString;
+
+ // ensure we have a server name or service name
+ if (casServerName == null && casServiceUrl == null) throw new
ServletException(
+ "need one of the following configuration "
+ + "parameters: edu.yale.its.tp.cas.client.filter.serviceUrl or
"
+ + "edu.yale.its.tp.cas.client.filter.serverName");
+
+ // use the given string if it's provided
+ if (casServiceUrl != null)
+ {
+ serviceString = URLEncoder.encode(casServiceUrl);
+ }
+ else
+ {
+ // otherwise, return our best guess at the service
+ serviceString = Util.getService(request, casServerName);
+ }
+
+ return serviceString;
+ }
+
+ /**
+ * Redirects the user to CAS, determining the service from the request.
+ */
+ private void redirectToCAS(HttpServletRequest request,
+ HttpServletResponse response) throws IOException, ServletException
+ {
+ String casLoginString = casLogin + "?service="
+ + getService((HttpServletRequest) request)
+ + ((casRenew) ? "&renew=true" : "")
+ + (casGateway ? "&gateway=true" : "");
+
+ ((HttpServletResponse) response).sendRedirect(casLoginString);
+ }
+}
Modified:
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/IdentityLoginModule.java
===================================================================
---
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/IdentityLoginModule.java 2007-05-24
22:23:32 UTC (rev 7331)
+++
branches/2_6_CAS_Integration/identity/src/main/org/jboss/portal/identity/auth/IdentityLoginModule.java 2007-05-25
02:37:52 UTC (rev 7332)
@@ -147,14 +147,29 @@
protected boolean validatePassword(final String inputPassword, String
expectedPassword)
{
+ HttpServletRequest request = null;
+ try
+ {
+ request = (HttpServletRequest)
PolicyContext.getContext("javax.servlet.http.HttpServletRequest");
+ }
+ catch(Exception e)
+ {
+ log.error(this,e);
+ throw new RuntimeException(e);
+ }
+
+ Object ssoSuccess = request.getAttribute("ssoSuccess");
+ if(ssoSuccess != null)
+ {
+ return true;
+ }
+
if (inputPassword != null)
{
try
{
try
- {
- HttpServletRequest request = (HttpServletRequest)
PolicyContext.getContext("javax.servlet.http.HttpServletRequest");
-
+ {
UserStatus userStatus = getUserStatus(inputPassword);
if (userStatus == UserStatus.DISABLE)