You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by pe...@apache.org on 2007/01/17 19:04:03 UTC

svn commit: r497104 - in /tomcat/container/tc5.5.x: modules/cluster/ modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ webapps/docs/

Author: pero
Date: Wed Jan 17 10:03:59 2007
New Revision: 497104

URL: http://svn.apache.org/viewvc?view=rev&rev=497104
Log:
Add clustered SSO code, submitted by Fabien Carrion
Backport form tomcat 6.0.x
Formatting source


Added:
    tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/
    tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ClusterSingleSignOn.java
    tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ClusterSingleSignOnListener.java
    tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/SingleSignOnMessage.java
    tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/mbeans-descriptors.xml
Modified:
    tomcat/container/tc5.5.x/modules/cluster/build.xml
    tomcat/container/tc5.5.x/webapps/docs/changelog.xml

Modified: tomcat/container/tc5.5.x/modules/cluster/build.xml
URL: http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/modules/cluster/build.xml?view=diff&rev=497104&r1=497103&r2=497104
==============================================================================
--- tomcat/container/tc5.5.x/modules/cluster/build.xml (original)
+++ tomcat/container/tc5.5.x/modules/cluster/build.xml Wed Jan 17 10:03:59 2007
@@ -100,6 +100,8 @@
     	  tofile="${catalina.build}/classes/org/apache/catalina/cluster/mcast/LocalStrings.properties"/>
     <copy file="${basedir}/src/share/org/apache/catalina/cluster/mcast/mbeans-descriptors.xml"
      	  tofile="${catalina.build}/classes/org/apache/catalina/cluster/mcast/mbeans-descriptors.xml"/>
+    <copy file="${basedir}/src/share/org/apache/catalina/cluster/authenticator/mbeans-descriptors.xml"
+     	  tofile="${catalina.build}/classes/org/apache/catalina/cluster/authenticator/mbeans-descriptors.xml"/>
    </target>
 
 
@@ -115,7 +117,7 @@
       version="true"
       windowtitle="Catalina Internal API Documentation"
       doctitle="Catalina API"
-      bottom="Copyright &#169; 2000-2002 Apache Software Foundation.  All Rights Reserved."
+      bottom="Copyright &#169; 2000-2007 Apache Software Foundation.  All Rights Reserved."
     />
   </target>
 

Added: tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ClusterSingleSignOn.java
URL: http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ClusterSingleSignOn.java?view=auto&rev=497104
==============================================================================
--- tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ClusterSingleSignOn.java (added)
+++ tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ClusterSingleSignOn.java Wed Jan 17 10:03:59 2007
@@ -0,0 +1,376 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.catalina.cluster.authenticator;
+
+
+import java.security.Principal;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Cluster;
+import org.apache.catalina.Engine;
+import org.apache.catalina.Host;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.Manager;
+import org.apache.catalina.Session;
+import org.apache.catalina.authenticator.SingleSignOn;
+import org.apache.catalina.cluster.CatalinaCluster;
+import org.apache.catalina.cluster.ClusterManager;
+import org.apache.catalina.cluster.ClusterValve;
+
+/**
+ * A <strong>Valve</strong> that supports a "single sign on" user experience on
+ * each nodes of a cluster, where the security identity of a user who successfully
+ * authenticates to one web application is propogated to other web applications and
+ * to other nodes cluster in the same security domain.  For successful use, the following
+ * requirements must be met:
+ * <ul>
+ * <li>This Valve must be configured on the Container that represents a
+ *     virtual host (typically an implementation of <code>Host</code>).</li>
+ * <li>The <code>Realm</code> that contains the shared user and role
+ *     information must be configured on the same Container (or a higher
+ *     one), and not overridden at the web application level.</li>
+ * <li>The web applications themselves must use one of the standard
+ *     Authenticators found in the
+ *     <code>org.apache.catalina.authenticator</code> package.</li>
+ * </ul>
+ *
+ * @author Fabien Carrion
+ */
+
+public class ClusterSingleSignOn
+    extends SingleSignOn implements ClusterValve {
+
+    // ----------------------------------------------------- Instance Variables
+
+    /**
+     * Descriptive information about this Valve implementation.
+     */
+    protected static String info =
+        "org.apache.catalina.cluster.authenticator.ClusterSingleSignOn/1.0";
+
+    protected int messageNumber = 0;
+
+    private ClusterSingleSignOnListener clusterSSOListener = null;
+
+    // ------------------------------------------------------------- Properties
+
+    private CatalinaCluster cluster = null;
+
+    /**
+     * Return descriptive information about this Valve implementation.
+     */
+    public String getInfo() {
+        return (info);
+    }
+
+    public CatalinaCluster getCluster() {
+        return cluster;
+    }
+
+    public void setCluster(CatalinaCluster cluster) {
+        this.cluster = cluster;
+    }
+
+    // ------------------------------------------------------ Lifecycle Methods
+
+    /**
+     * Prepare for the beginning of active use of the public methods of this
+     * component.  This method should be called after <code>configure()</code>,
+     * and before any of the public methods of the component are utilized.
+     *
+     * @exception LifecycleException if this component detects a fatal error
+     *  that prevents this component from being used
+     */
+    public void start() throws LifecycleException {
+        super.start();
+        clusterSSOListener = new ClusterSingleSignOnListener();
+        clusterSSOListener.setClusterSSO(this);
+        // Load the cluster component, if any
+        try {
+            //the channel is already running
+            Cluster cluster = getCluster();
+            // stop remove cluster binding
+            if(cluster == null) {
+                Container host = getContainer();
+                if(host != null && host instanceof Host) {
+                    cluster = host.getCluster();
+                    if(cluster != null && cluster instanceof CatalinaCluster) {
+                        setCluster((CatalinaCluster) cluster);
+                    } else {
+                        Container engine = host.getParent();
+                        if(engine != null && engine instanceof Engine) {
+                            cluster = engine.getCluster();
+                            if(cluster != null && cluster instanceof CatalinaCluster) {
+                                setCluster((CatalinaCluster) cluster);
+                            }
+                        } else {
+                            cluster = null;
+                        }
+                    }
+                }
+            }
+            if (cluster == null) {
+                throw new LifecycleException
+                ("There is no Cluster for ClusterSingleSignOn");
+            }
+            ((CatalinaCluster)cluster).addClusterListener(clusterSSOListener);
+        } catch (Throwable t) {
+            throw new LifecycleException
+            ("ClusterSingleSignOn exception during clusterLoad " + t);
+        }
+    }
+
+    /**
+     * Gracefully terminate the active use of the public methods of this
+     * component.  This method should be the last one called on a given
+     * instance of this component.
+     *
+     * @exception LifecycleException if this component detects a fatal error
+     *  that needs to be reported
+     */
+    public void stop() throws LifecycleException {
+        super.stop();
+        if (getCluster() != null && getCluster() instanceof CatalinaCluster) {
+            getCluster().removeClusterListener(clusterSSOListener);
+        }
+    }
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * Return a String rendering of this object.
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer("ClusterSingleSignOn[");
+        if (container == null )
+            sb.append("Container is null");
+        else
+            sb.append(container.getName());
+        sb.append("]");
+        return (sb.toString());
+    }
+
+    // ------------------------------------------------------ Protected Methods
+
+    /**
+     * Notify the cluster of the addition of a Session to
+     * an SSO session and associate the specified single
+     * sign on identifier with the specified Session on the
+     * local node.
+     *
+     * @param ssoId Single sign on identifier
+     * @param session Session to be associated
+     */
+    protected void associate(String ssoId, Session session) {
+        if (cluster != null) {
+            messageNumber++;
+            SingleSignOnMessage msg =
+                new SingleSignOnMessage(cluster.getLocalMember(),
+                        ssoId, session.getId());
+            Manager mgr = session.getManager();
+            if ((mgr != null) && (mgr instanceof ClusterManager))
+                msg.setContextName(((ClusterManager) mgr).getName());
+            msg.setAction(SingleSignOnMessage.ADD_SESSION);
+            cluster.sendClusterDomain(msg);
+            if (containerLog.isDebugEnabled())
+                containerLog.debug("SingleSignOnMessage Send with action "
+                        + msg.getAction());
+        }
+        associateLocal(ssoId, session);
+
+    }
+
+    protected void associateLocal(String ssoId, Session session) {
+        super.associate(ssoId, session);
+    }
+
+    /**
+     * Notify the cluster of the removal of a Session from an
+     * SSO session and deregister the specified session. If it is the last
+     * session, then also get rid of the single sign on identifier on the
+     * local node.
+     *
+     * @param ssoId Single sign on identifier
+     * @param session Session to be deregistered
+     */
+    protected void deregister(String ssoId, Session session) {
+        if (cluster != null) {
+            messageNumber++;
+            SingleSignOnMessage msg =
+                new SingleSignOnMessage(cluster.getLocalMember(),
+                        ssoId, session.getId());
+            Manager mgr = session.getManager();
+            if ((mgr != null) && (mgr instanceof ClusterManager))
+                msg.setContextName(((ClusterManager) mgr).getName());
+            msg.setAction(SingleSignOnMessage.DEREGISTER_SESSION);
+            cluster.sendClusterDomain(msg);
+            if (containerLog.isDebugEnabled())
+                containerLog.debug("SingleSignOnMessage Send with action "
+				   + msg.getAction());
+        }
+        deregisterLocal(ssoId, session);
+    }
+
+    protected void deregisterLocal(String ssoId, Session session) {
+        super.deregister(ssoId, session);
+    }
+
+    /**
+     * Notifies the cluster that a single sign on session
+     * has been terminated due to a user logout, deregister
+     * the specified single sign on identifier, and invalidate
+     * any associated sessions on the local node.
+     *
+     * @param ssoId Single sign on identifier to deregister
+     */
+    protected void deregister(String ssoId) {
+        if (cluster != null) {
+            messageNumber++;
+            SingleSignOnMessage msg =
+                new SingleSignOnMessage(cluster.getLocalMember(),
+                        ssoId, null);
+            msg.setAction(SingleSignOnMessage.LOGOUT_SESSION);
+            cluster.sendClusterDomain(msg);
+            if (containerLog.isDebugEnabled())
+                containerLog.debug("SingleSignOnMessage Send with action "
+                        + msg.getAction());
+        }
+        deregisterLocal(ssoId);
+    }
+
+    protected void deregisterLocal(String ssoId) {
+        super.deregister(ssoId);
+    }
+
+    /**
+     * Notifies the cluster of the creation of a new SSO entry
+     * and register the specified Principal as being associated
+     * with the specified value for the single sign on identifier.
+     *
+     * @param ssoId Single sign on identifier to register
+     * @param principal Associated user principal that is identified
+     * @param authType Authentication type used to authenticate this
+     *  user principal
+     * @param username Username used to authenticate this user
+     * @param password Password used to authenticate this user
+     */
+    protected void register(String ssoId, Principal principal, String authType,
+                  String username, String password) {
+    	if (cluster != null) {
+    	    messageNumber++;
+    	    SingleSignOnMessage msg =
+    		new SingleSignOnMessage(cluster.getLocalMember(),
+    					ssoId, null);
+    	    msg.setAction(SingleSignOnMessage.REGISTER_SESSION);
+    	    msg.setAuthType(authType);
+    	    msg.setUsername(username);
+    	    msg.setPassword(password);
+    	    cluster.sendClusterDomain(msg);
+    	    if (containerLog.isDebugEnabled())
+    		containerLog.debug("SingleSignOnMessage Send with action "
+    				   + msg.getAction());
+    	}
+    	registerLocal(ssoId, principal, authType, username, password);
+    }
+
+    protected void registerLocal(String ssoId, Principal principal, String authType,
+                  String username, String password) {
+        super.register(ssoId, principal, authType, username, password);
+    }
+
+    /**
+     * Notifies the cluster of an update of the security credentials
+     * associated with an SSO session. Updates any <code>SingleSignOnEntry</code>
+     * found under key <code>ssoId</code> with the given authentication data.
+     * <p>
+     * The purpose of this method is to allow an SSO entry that was
+     * established without a username/password combination (i.e. established
+     * following DIGEST or CLIENT-CERT authentication) to be updated with
+     * a username and password if one becomes available through a subsequent
+     * BASIC or FORM authentication.  The SSO entry will then be usable for
+     * reauthentication.
+     * <p>
+     * <b>NOTE:</b> Only updates the SSO entry if a call to
+     * <code>SingleSignOnEntry.getCanReauthenticate()</code> returns
+     * <code>false</code>; otherwise, it is assumed that the SSO entry already
+     * has sufficient information to allow reauthentication and that no update
+     * is needed.
+     *
+     * @param ssoId     identifier of Single sign to be updated
+     * @param principal the <code>Principal</code> returned by the latest
+     *                  call to <code>Realm.authenticate</code>.
+     * @param authType  the type of authenticator used (BASIC, CLIENT-CERT,
+     *                  DIGEST or FORM)
+     * @param username  the username (if any) used for the authentication
+     * @param password  the password (if any) used for the authentication
+     */
+    protected void update(String ssoId, Principal principal, String authType,
+                          String username, String password) {
+        if (cluster != null) {
+            messageNumber++;
+            SingleSignOnMessage msg =
+                new SingleSignOnMessage(cluster.getLocalMember(),
+                        ssoId, null);
+            msg.setAction(SingleSignOnMessage.UPDATE_SESSION);
+            msg.setAuthType(authType);
+            msg.setUsername(username);
+            msg.setPassword(password);
+            cluster.sendClusterDomain(msg);
+            if (containerLog.isDebugEnabled())
+                containerLog.debug("SingleSignOnMessage Send with action "
+                        + msg.getAction());
+        }
+        updateLocal(ssoId, principal, authType, username, password);
+    }
+
+    protected void updateLocal(String ssoId, Principal principal, String authType,
+                          String username, String password) {
+        super.update(ssoId, principal, authType, username, password);
+    }
+
+    /**
+     * Remove a single Session from a SingleSignOn and notify the cluster
+     * of the removal. Called when a session is timed out and no longer active.
+     *
+     * @param ssoId Single sign on identifier from which to remove the session.
+     * @param session the session to be removed.
+     */
+    protected void removeSession(String ssoId, Session session) {
+        if (cluster != null) {
+            messageNumber++;
+            SingleSignOnMessage msg =
+                new SingleSignOnMessage(cluster.getLocalMember(),
+                        ssoId, session.getId());
+            Manager mgr = session.getManager();
+            if ((mgr != null) && (mgr instanceof ClusterManager))
+                msg.setContextName(((ClusterManager) mgr).getName());
+            msg.setAction(SingleSignOnMessage.REMOVE_SESSION);
+            cluster.sendClusterDomain(msg);
+            if (containerLog.isDebugEnabled())
+                containerLog.debug("SingleSignOnMessage Send with action "
+                        + msg.getAction());
+        }
+        removeSessionLocal(ssoId, session);
+    }
+
+    protected void removeSessionLocal(String ssoId, Session session) {
+        super.removeSession(ssoId, session);
+    }
+
+}

Added: tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ClusterSingleSignOnListener.java
URL: http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ClusterSingleSignOnListener.java?view=auto&rev=497104
==============================================================================
--- tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ClusterSingleSignOnListener.java (added)
+++ tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/ClusterSingleSignOnListener.java Wed Jan 17 10:03:59 2007
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.cluster.authenticator;
+
+import java.util.Map;
+import java.io.IOException;
+
+import org.apache.catalina.Session;
+import org.apache.catalina.cluster.ClusterManager;
+import org.apache.catalina.cluster.ClusterMessage;
+import org.apache.catalina.cluster.session.ClusterListener;
+
+/**
+ * Receive replicated SingleSignOnMessage form other cluster node.
+ * 
+ * @author Fabien Carrion
+ */
+public class ClusterSingleSignOnListener extends ClusterListener {
+
+    /**
+     * The descriptive information about this implementation.
+     */
+    protected static final String info = "org.apache.catalina.cluster.authenticator.ClusterSingleSignOnListener/1.0";
+
+    // ------------------------------------------------------------- Properties
+
+    private ClusterSingleSignOn clusterSSO = null;
+
+    // --Constructor---------------------------------------------
+
+    public ClusterSingleSignOnListener() {
+    }
+
+    // --Logic---------------------------------------------------
+
+    /**
+     * Return descriptive information about this implementation.
+     */
+    public String getInfo() {
+
+        return (info);
+
+    }
+
+    public ClusterSingleSignOn getClusterSSO() {
+
+        return clusterSSO;
+
+    }
+
+    public void setClusterSSO(ClusterSingleSignOn clusterSSO) {
+
+        this.clusterSSO = clusterSSO;
+
+    }
+
+    /**
+     * Callback from the cluster, when a message is received, The cluster will
+     * broadcast it invoking the messageReceived on the receiver.
+     * 
+     * @param myobj
+     *            ClusterMessage - the message received from the cluster
+     */
+    public void messageReceived(ClusterMessage myobj) {
+        if (myobj != null && myobj instanceof SingleSignOnMessage) {
+            SingleSignOnMessage msg = (SingleSignOnMessage) myobj;
+            int action = msg.getAction();
+            Session session = null;
+
+            if (log.isDebugEnabled())
+                log.debug("SingleSignOnMessage Received with action "
+                        + msg.getAction());
+
+            switch (action) {
+            case SingleSignOnMessage.ADD_SESSION:
+                session = getSession(msg.getSessionId(), msg.getContextName());
+                if (session != null)
+                    clusterSSO.associateLocal(msg.getSsoId(), session);
+                break;
+            case SingleSignOnMessage.DEREGISTER_SESSION:
+                session = getSession(msg.getSessionId(), msg.getContextName());
+                if (session != null)
+                    clusterSSO.deregisterLocal(msg.getSsoId(), session);
+                break;
+            case SingleSignOnMessage.LOGOUT_SESSION:
+                clusterSSO.deregisterLocal(msg.getSsoId());
+                break;
+            case SingleSignOnMessage.REGISTER_SESSION:
+                clusterSSO.registerLocal(msg.getSsoId(), null, msg
+                        .getAuthType(), msg.getUsername(), msg.getPassword());
+                break;
+            case SingleSignOnMessage.UPDATE_SESSION:
+                clusterSSO.updateLocal(msg.getSsoId(), null, msg.getAuthType(),
+                        msg.getUsername(), msg.getPassword());
+                break;
+            case SingleSignOnMessage.REMOVE_SESSION:
+                session = getSession(msg.getSessionId(), msg.getContextName());
+                if (session != null)
+                    clusterSSO.removeSessionLocal(msg.getSsoId(), session);
+                break;
+            }
+        }
+    }
+
+    /**
+     * Accept only SingleSignOnMessage
+     * 
+     * @param msg
+     *            ClusterMessage
+     * @return boolean - returns true to indicate that messageReceived should be
+     *         invoked. If false is returned, the messageReceived method will
+     *         not be invoked.
+     */
+    public boolean accept(ClusterMessage msg) {
+        return (msg instanceof SingleSignOnMessage);
+    }
+
+    private Session getSession(String sessionId, String ctxname) {
+
+        Map managers = clusterSSO.getCluster().getManagers();
+        Session session = null;
+
+        if (ctxname == null) {
+            java.util.Iterator i = managers.keySet().iterator();
+            while (i.hasNext()) {
+                String key = (String) i.next();
+                ClusterManager mgr = (ClusterManager) managers.get(key);
+                if (mgr != null) {
+                    try {
+                        session = mgr.findSession(sessionId);
+                    } catch (IOException io) {
+                        log.error("Session doesn't exist:" + io);
+                    }
+                    return session;
+                } else {
+                    // this happens a lot before the system has started
+                    // up
+                    if (log.isDebugEnabled())
+                        log.debug("Context manager doesn't exist:" + key);
+                }
+            }
+        } else {
+            ClusterManager mgr = (ClusterManager) managers.get(ctxname);
+            if (mgr != null) {
+                try {
+                    session = mgr.findSession(sessionId);
+                } catch (IOException io) {
+                    log.error("Session doesn't exist:" + io);
+                }
+                return session;
+            } else {
+                log.error("Context manager doesn't exist:" + ctxname);
+            }
+        }
+        return null;
+    }
+}

Added: tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/SingleSignOnMessage.java
URL: http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/SingleSignOnMessage.java?view=auto&rev=497104
==============================================================================
--- tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/SingleSignOnMessage.java (added)
+++ tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/SingleSignOnMessage.java Wed Jan 17 10:03:59 2007
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.catalina.cluster.authenticator;
+
+import java.io.Serializable;
+
+import org.apache.catalina.cluster.ClusterMessage;
+import org.apache.catalina.cluster.Member;
+
+/**
+ * Contains the SingleSignOn data, read and written by the ClusterSingleSignOn
+ * 
+ * @author Fabien Carrion
+ */
+
+public class SingleSignOnMessage implements ClusterMessage, Serializable {
+
+    public static final int ADD_SESSION = 1;
+
+    public static final int DEREGISTER_SESSION = 2;
+
+    public static final int LOGOUT_SESSION = 3;
+
+    public static final int REGISTER_SESSION = 4;
+
+    public static final int UPDATE_SESSION = 5;
+
+    public static final int REMOVE_SESSION = 6;
+
+    private int action = -1;
+
+    private String ssoId = null;
+
+    private String ctxname = null;
+
+    private String sessionId = null;
+
+    private String authType = null;
+
+    private String password = null;
+
+    private String username = null;
+
+    private Member address = null;
+
+    private long timestamp = 0;
+
+    private String uniqueId = null;
+
+    private int resend = ClusterMessage.FLAG_DEFAULT;
+
+    private int compress = ClusterMessage.FLAG_DEFAULT;
+
+    public SingleSignOnMessage(Member source, String ssoId, String sessionId) {
+        this.address = source;
+        this.ssoId = ssoId;
+        this.sessionId = sessionId;
+    }
+
+    /**
+     * Get the address that this message originated from. This would be set if
+     * the message was being relayed from a host other than the one that
+     * originally sent it.
+     */
+    public Member getAddress() {
+        return address;
+    }
+
+    /**
+     * Called by the cluster before sending it to the other nodes.
+     * 
+     * @param member
+     *            Member
+     */
+    public void setAddress(Member member) {
+        this.address = member;
+    }
+
+    /**
+     * Timestamp message.
+     * 
+     * @return long
+     */
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    /**
+     * Called by the cluster before sending out the message.
+     * 
+     * @param timestamp
+     *            The timestamp
+     */
+    public void setTimestamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    /**
+     * Each message must have a unique ID, in case of using async replication,
+     * and a smart queue, this id is used to replace messages not yet sent.
+     * 
+     * @return String
+     */
+    public String getUniqueId() {
+        if (this.uniqueId != null)
+            return this.uniqueId;
+        StringBuffer result = new StringBuffer(getSsoId());
+        result.append("#-#");
+        result.append(System.currentTimeMillis());
+        return result.toString();
+    }
+
+    public void setUniqueId(String uniqueId) {
+        this.uniqueId = uniqueId;
+    }
+
+    public int getAction() {
+        return action;
+    }
+
+    public void setAction(int action) {
+        this.action = action;
+    }
+
+    public String getSsoId() {
+        return ssoId;
+    }
+
+    public void setSsoId(String ssoId) {
+        this.ssoId = ssoId;
+    }
+
+    public String getContextName() {
+        return ctxname;
+    }
+
+    public void setContextName(String ctxname) {
+        this.ctxname = ctxname;
+    }
+
+    public String getSessionId() {
+        return sessionId;
+    }
+
+    public void setSessionId(String sessionId) {
+        this.sessionId = sessionId;
+    }
+
+    public String getAuthType() {
+        return authType;
+    }
+
+    public void setAuthType(String authType) {
+        this.authType = authType;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    /**
+     * @return Returns the compress.
+     * @since 5.5.10
+     */
+    public int getCompress() {
+        return compress;
+    }
+
+    /**
+     * @param compress
+     *            The compress to set.
+     * @since 5.5.10
+     */
+    public void setCompress(int compress) {
+        this.compress = compress;
+    }
+
+    /**
+     * @return Returns the resend.
+     * @since 5.5.10
+     */
+    public int getResend() {
+        return resend;
+    }
+
+    /**
+     * @param resend
+     *            The resend to set.
+     * @since 5.5.10
+     */
+    public void setResend(int resend) {
+        this.resend = resend;
+    }
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * Return a String rendering of this object.
+     */
+    public String toString() {
+
+        StringBuffer sb = new StringBuffer("SingleSignOnMessage[action=");
+        sb.append(getAction()).append(", ssoId=").append(getSsoId());
+        sb.append(", sessionId=").append(getSessionId()).append(", username=");
+        sb.append(getUsername()).append("]");
+        return (sb.toString());
+
+    }
+
+}

Added: tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/mbeans-descriptors.xml
URL: http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/mbeans-descriptors.xml?view=auto&rev=497104
==============================================================================
--- tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/mbeans-descriptors.xml (added)
+++ tomcat/container/tc5.5.x/modules/cluster/src/share/org/apache/catalina/cluster/authenticator/mbeans-descriptors.xml Wed Jan 17 10:03:59 2007
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<mbeans-descriptors>
+
+  <mbean name="ClusterSingleSignOn"
+         description="A Valve that supports a 'single signon' user experience on a whole cluster"
+         domain="Catalina"
+         group="Valve"
+         type="org.apache.catalina.cluster.authenticator.ClusterSingleSignOn">
+
+    <attribute name="className"
+               description="Fully qualified class name of the managed object"
+               type="java.lang.String"
+               writeable="false"/>
+
+    <attribute name="requireReauthentication"
+               description="Should we attempt to reauthenticate each request against the security Realm?"
+               type="boolean"/>
+
+    <attribute name="cookieDomain"
+               description="(Optiona) Domain to be used by sso cookies"
+               type="java.lang.String" />
+
+  </mbean>
+
+</mbeans-descriptors>

Modified: tomcat/container/tc5.5.x/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/container/tc5.5.x/webapps/docs/changelog.xml?view=diff&rev=497104&r1=497103&r2=497104
==============================================================================
--- tomcat/container/tc5.5.x/webapps/docs/changelog.xml (original)
+++ tomcat/container/tc5.5.x/webapps/docs/changelog.xml Wed Jan 17 10:03:59 2007
@@ -350,6 +350,10 @@
   <subsection name="Cluster">
     <changelog>
       <add>
+        Add clustered SSO code and backport feature from Tomcat 6.0.x,
+        submitted by Fabien Carrion (pero)
+      </add>    
+      <add>
         Add better recovery at FastAsyncQueueSender. Made the startegy more robust for temporary connection problems (pero)
       </add>
     </changelog>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org