📄 singlesignon.java
字号:
/*
* $Header: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/authenticator/SingleSignOn.java,v 1.11 2003/11/25 08:02:05 remm Exp $
* $Revision: 1.11 $
* $Date: 2003/11/25 08:02:05 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.catalina.authenticator;
import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.HttpRequest;
import org.apache.catalina.HttpResponse;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Logger;
import org.apache.catalina.Request;
import org.apache.catalina.Response;
import org.apache.catalina.Session;
import org.apache.catalina.SessionEvent;
import org.apache.catalina.SessionListener;
import org.apache.catalina.ValveContext;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
import org.apache.catalina.valves.ValveBase;
/**
* A <strong>Valve</strong> that supports a "single sign on" user experience,
* where the security identity of a user who successfully authenticates to one
* web application is propogated to other web applications 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 Craig R. McClanahan
* @version $Revision: 1.11 $ $Date: 2003/11/25 08:02:05 $
*/
public class SingleSignOn
extends ValveBase
implements Lifecycle, SessionListener {
// ----------------------------------------------------- Instance Variables
/**
* The cache of SingleSignOnEntry instances for authenticated Principals,
* keyed by the cookie value that is used to select them.
*/
protected HashMap cache = new HashMap();
/**
* The debugging detail level for this component.
*/
protected int debug = 0;
/**
* Descriptive information about this Valve implementation.
*/
protected static String info =
"org.apache.catalina.authenticator.SingleSignOn";
/**
* The lifecycle event support for this component.
*/
protected LifecycleSupport lifecycle = new LifecycleSupport(this);
/**
* Indicates whether this valve should require a downstream Authenticator to
* reauthenticate each request, or if it itself can bind a UserPrincipal
* and AuthType object to the request.
*/
private boolean requireReauthentication = false;
/**
* The cache of single sign on identifiers, keyed by the Session that is
* associated with them.
*/
protected HashMap reverse = new HashMap();
/**
* The string manager for this package.
*/
protected final static StringManager sm =
StringManager.getManager(Constants.Package);
/**
* Component started flag.
*/
protected boolean started = false;
// ------------------------------------------------------------- Properties
/**
* Return the debugging detail level.
*/
public int getDebug() {
return (this.debug);
}
/**
* Set the debugging detail level.
*
* @param debug The new debugging detail level
*/
public void setDebug(int debug) {
this.debug = debug;
}
/**
* Gets whether each request needs to be reauthenticated (by an
* Authenticator downstream in the pipeline) to the security
* <code>Realm</code>, or if this Valve can itself bind security info
* to the request based on the presence of a valid SSO entry without
* rechecking with the <code>Realm</code..
*
* @return <code>true</code> if it is required that a downstream
* Authenticator reauthenticate each request before calls to
* <code>HttpServletRequest.setUserPrincipal()</code>
* and <code>HttpServletRequest.setAuthType()</code> are made;
* <code>false</code> if the <code>Valve</code> can itself make
* those calls relying on the presence of a valid SingleSignOn
* entry associated with the request.
*
* @see #setRequireReauthentication
*/
public boolean getRequireReauthentication()
{
return requireReauthentication;
}
/**
* Sets whether each request needs to be reauthenticated (by an
* Authenticator downstream in the pipeline) to the security
* <code>Realm</code>, or if this Valve can itself bind security info
* to the request, based on the presence of a valid SSO entry, without
* rechecking with the <code>Realm</code.
* <p>
* If this property is <code>false</code> (the default), this
* <code>Valve</code> will bind a UserPrincipal and AuthType to the request
* if a valid SSO entry is associated with the request. It will not notify
* the security <code>Realm</code> of the incoming request.
* <p>
* This property should be set to <code>true</code> if the overall server
* configuration requires that the <code>Realm</code> reauthenticate each
* request thread. An example of such a configuration would be one where
* the <code>Realm</code> implementation provides security for both a
* web tier and an associated EJB tier, and needs to set security
* credentials on each request thread in order to support EJB access.
* <p>
* If this property is set to <code>true</code>, this Valve will set flags
* on the request notifying the downstream Authenticator that the request
* is associated with an SSO session. The Authenticator will then call its
* {@link AuthenticatorBase#reauthenticateFromSSO reauthenticateFromSSO}
* method to attempt to reauthenticate the request to the
* <code>Realm</code>, using any credentials that were cached with this
* Valve.
* <p>
* The default value of this property is <code>false</code>, in order
* to maintain backward compatibility with previous versions of Tomcat.
*
* @param required <code>true</code> if it is required that a downstream
* Authenticator reauthenticate each request before calls
* to <code>HttpServletRequest.setUserPrincipal()</code>
* and <code>HttpServletRequest.setAuthType()</code> are
* made; <code>false</code> if the <code>Valve</code> can
* itself make those calls relying on the presence of a
* valid SingleSignOn entry associated with the request.
*
* @see AuthenticatorBase#reauthenticateFromSSO
*/
public void setRequireReauthentication(boolean required)
{
this.requireReauthentication = required;
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Add a lifecycle event listener to this component.
*
* @param listener The listener to add
*/
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
/**
* Get the lifecycle listeners associated with this lifecycle. If this
* Lifecycle has no listeners registered, a zero-length array is returned.
*/
public LifecycleListener[] findLifecycleListeners() {
return lifecycle.findLifecycleListeners();
}
/**
* Remove a lifecycle event listener from this component.
*
* @param listener The listener to remove
*/
public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
/**
* 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 {
// Validate and update our current component state
if (started)
throw new LifecycleException
(sm.getString("authenticator.alreadyStarted"));
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
if (debug >= 1)
log("Started");
}
/**
* 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 {
// Validate and update our current component state
if (!started)
throw new LifecycleException
(sm.getString("authenticator.notStarted"));
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
if (debug >= 1)
log("Stopped");
}
// ------------------------------------------------ SessionListener Methods
/**
* Acknowledge the occurrence of the specified event.
*
* @param event SessionEvent that has occurred
*/
public void sessionEvent(SessionEvent event) {
// We only care about session destroyed events
if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType()))
return;
// Look up the single session id associated with this session (if any)
Session session = event.getSession();
if (debug >= 1)
log("Process session destroyed on " + session);
String ssoId = null;
synchronized (reverse) {
ssoId = (String) reverse.get(session);
}
if (ssoId == null)
return;
// Was the session destroyed as the result of a timeout?
// If so, we'll just remove the expired session from the
// SSO. If the session was logged out, we'll log out
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -