Author: remm
Date: Tue Dec  5 13:49:09 2006
New Revision: 482797

URL: http://svn.apache.org/viewvc?view=rev&rev=482797
Log:
- Add experimental clustered SSO code.
- Submitted by Fabien Carrion.

Added:
    tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/
    
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
   (with props)
    
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOnListener.java
   (with props)
    
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/SingleSignOnMessage.java
   (with props)
    
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/mbeans-descriptors.xml
   (with props)
Modified:
    
tomcat/tc6.0.x/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java

Modified: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java?view=diff&rev=482797&r1=482796&r2=482797
==============================================================================
--- 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java 
(original)
+++ 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java 
Tue Dec  5 13:49:09 2006
@@ -401,7 +401,7 @@
         if (entry != null) {
             if (containerLog.isDebugEnabled())
                 containerLog.debug(" Found cached principal '" +
-                    entry.getPrincipal().getName() + "' with auth type '" +
+                    (entry.getPrincipal() != null ? 
entry.getPrincipal().getName() : "") + "' with auth type '" +
                     entry.getAuthType() + "'");
             request.setNote(Constants.REQ_SSOID_NOTE, cookie.getValue());
             // Only set security elements if reauthentication is not required
@@ -600,7 +600,7 @@
 
         if (containerLog.isDebugEnabled())
             containerLog.debug("Registering sso id '" + ssoId + "' for user '" 
+
-                principal.getName() + "' with auth type '" + authType + "'");
+                (principal != null ? principal.getName() : "") + "' with auth 
type '" + authType + "'");
 
         synchronized (cache) {
             cache.put(ssoId, new SingleSignOnEntry(principal, authType,

Added: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java?view=auto&rev=482797
==============================================================================
--- 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
 (added)
+++ 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
 Tue Dec  5 13:49:09 2006
@@ -0,0 +1,448 @@
+/*
+ * Copyright 1999-2001,2004-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.ha.authenticator;
+
+
+import java.security.Principal;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Context;
+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.authenticator.SingleSignOnEntry;
+import org.apache.catalina.ha.CatalinaCluster;
+import org.apache.catalina.ha.ClusterManager;
+
+
+
+/**
+ * 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 {
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * Descriptive information about this Valve implementation.
+     */
+    protected static String info =
+        "org.apache.catalina.cluster.authenticator.ClusterSingleSignOn";
+
+    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);
+                       getCluster().addClusterListener(clusterSSOListener);
+                   } else {
+                       Container engine = host.getParent();
+                       if(engine != null && engine instanceof Engine) {
+                           cluster = engine.getCluster();
+                           if(cluster != null && cluster instanceof 
CatalinaCluster) {
+                               setCluster((CatalinaCluster) cluster);
+                               
getCluster().addClusterListener(clusterSSOListener);
+                           }
+                       } else {
+                           cluster = null;
+                       }
+                   }
+                }
+            }
+            if (cluster == null) {
+               throw new LifecycleException
+                   ("There is no Cluster for ClusterSingleSignOn");
+            }
+
+        } 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);
+       
+    }
+
+}

Propchange: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOnListener.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOnListener.java?view=auto&rev=482797
==============================================================================
--- 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOnListener.java
 (added)
+++ 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOnListener.java
 Tue Dec  5 13:49:09 2006
@@ -0,0 +1,180 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * Licensed 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.ha.authenticator;
+
+import java.util.Map;
+import java.io.IOException;
+
+import org.apache.catalina.Session;
+import org.apache.catalina.authenticator.SingleSignOnEntry;
+import org.apache.catalina.ha.ClusterManager;
+import org.apache.catalina.ha.ClusterMessage;
+import org.apache.catalina.ha.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.session.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 if (log.isErrorEnabled())
+               log.error("Context manager doesn't exist:" + ctxname);
+       }
+
+       return null;
+    }
+}
+

Propchange: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOnListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/SingleSignOnMessage.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/SingleSignOnMessage.java?view=auto&rev=482797
==============================================================================
--- 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/SingleSignOnMessage.java
 (added)
+++ 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/SingleSignOnMessage.java
 Tue Dec  5 13:49:09 2006
@@ -0,0 +1,187 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.ha.authenticator;
+
+import java.io.Serializable;
+
+import org.apache.catalina.ha.ClusterMessage;
+import org.apache.catalina.tribes.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;
+
+    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 = address;
+    }
+
+    /**
+     * 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;
+    }
+
+
+    // --------------------------------------------------------- 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());
+
+    }
+
+}

Propchange: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/SingleSignOnMessage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/mbeans-descriptors.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/mbeans-descriptors.xml?view=auto&rev=482797
==============================================================================
--- 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/mbeans-descriptors.xml
 (added)
+++ 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/mbeans-descriptors.xml
 Tue Dec  5 13:49:09 2006
@@ -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>

Propchange: 
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/authenticator/mbeans-descriptors.xml
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to