| Method from org.apache.catalina.authenticator.SingleSignOn Detail: |
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
Add a lifecycle event listener to this component. |
protected void associate(String ssoId,
Session session) {
if (containerLog.isDebugEnabled())
containerLog.debug("Associate sso id " + ssoId + " with session " + session);
SingleSignOnEntry sso = lookup(ssoId);
if (sso != null)
sso.addSession(this, session);
synchronized (reverse) {
reverse.put(session, ssoId);
}
}
Associate the specified single sign on identifier with the
specified Session. |
protected void deregister(String ssoId) {
if (containerLog.isDebugEnabled())
containerLog.debug("Deregistering sso id '" + ssoId + "'");
// Look up and remove the corresponding SingleSignOnEntry
SingleSignOnEntry sso = null;
synchronized (cache) {
sso = (SingleSignOnEntry) cache.remove(ssoId);
}
if (sso == null)
return;
// Expire any associated sessions
Session sessions[] = sso.findSessions();
for (int i = 0; i < sessions.length; i++) {
if (containerLog.isTraceEnabled())
containerLog.trace(" Invalidating session " + sessions[i]);
// Remove from reverse cache first to avoid recursion
synchronized (reverse) {
reverse.remove(sessions[i]);
}
// Invalidate this session
sessions[i].expire();
}
// NOTE: Clients may still possess the old single sign on cookie,
// but it will be removed on the next request since it is no longer
// in the cache
}
Deregister the specified single sign on identifier, and invalidate
any associated sessions. |
protected void deregister(String ssoId,
Session session) {
synchronized (reverse) {
reverse.remove(session);
}
SingleSignOnEntry sso = lookup(ssoId);
if ( sso == null )
return;
sso.removeSession( session );
// see if we are the last session, if so blow away ssoId
Session sessions[] = sso.findSessions();
if ( sessions == null || sessions.length == 0 ) {
synchronized (cache) {
sso = (SingleSignOnEntry) cache.remove(ssoId);
}
}
}
Deregister the specified session. If it is the last session,
then also get rid of the single sign on identifier |
public LifecycleListener[] findLifecycleListeners() {
return lifecycle.findLifecycleListeners();
}
Get the lifecycle listeners associated with this lifecycle. If this
Lifecycle has no listeners registered, a zero-length array is returned. |
public String getCookieDomain() {
// ------------------------------------------------------------- Properties
return cookieDomain;
}
Returns the optional cookie domain.
May return null. |
public String getInfo() {
return (info);
}
Return descriptive information about this Valve implementation. |
public boolean getRequireReauthentication() {
return requireReauthentication;
}
Gets whether each request needs to be reauthenticated (by an
Authenticator downstream in the pipeline) to the security
Realm, 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 Realm |
public void invoke(Request request,
Response response) throws IOException, ServletException {
request.removeNote(Constants.REQ_SSOID_NOTE);
// Has a valid user already been authenticated?
if (containerLog.isDebugEnabled())
containerLog.debug("Process request for '" + request.getRequestURI() + "'");
if (request.getUserPrincipal() != null) {
if (containerLog.isDebugEnabled())
containerLog.debug(" Principal '" + request.getUserPrincipal().getName() +
"' has already been authenticated");
getNext().invoke(request, response);
return;
}
// Check for the single sign on cookie
if (containerLog.isDebugEnabled())
containerLog.debug(" Checking for SSO cookie");
Cookie cookie = null;
Cookie cookies[] = request.getCookies();
if (cookies == null)
cookies = new Cookie[0];
for (int i = 0; i < cookies.length; i++) {
if (Constants.SINGLE_SIGN_ON_COOKIE.equals(cookies[i].getName())) {
cookie = cookies[i];
break;
}
}
if (cookie == null) {
if (containerLog.isDebugEnabled())
containerLog.debug(" SSO cookie is not present");
getNext().invoke(request, response);
return;
}
// Look up the cached Principal associated with this cookie value
if (containerLog.isDebugEnabled())
containerLog.debug(" Checking for cached principal for " + cookie.getValue());
SingleSignOnEntry entry = lookup(cookie.getValue());
if (entry != null) {
if (containerLog.isDebugEnabled())
containerLog.debug(" Found cached principal '" +
(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
if (!getRequireReauthentication()) {
request.setAuthType(entry.getAuthType());
request.setUserPrincipal(entry.getPrincipal());
}
} else {
if (containerLog.isDebugEnabled())
containerLog.debug(" No cached principal found, erasing SSO cookie");
cookie.setMaxAge(0);
response.addCookie(cookie);
}
// Invoke the next Valve in our pipeline
getNext().invoke(request, response);
}
Perform single-sign-on support processing for this request. |
protected SingleSignOnEntry lookup(String ssoId) {
synchronized (cache) {
return ((SingleSignOnEntry) cache.get(ssoId));
}
}
Look up and return the cached SingleSignOn entry associated with this
sso id value, if there is one; otherwise return null. |
protected boolean reauthenticate(String ssoId,
Realm realm,
Request request) {
if (ssoId == null || realm == null)
return false;
boolean reauthenticated = false;
SingleSignOnEntry entry = lookup(ssoId);
if (entry != null && entry.getCanReauthenticate()) {
String username = entry.getUsername();
if (username != null) {
Principal reauthPrincipal =
realm.authenticate(username, entry.getPassword());
if (reauthPrincipal != null) {
reauthenticated = true;
// Bind the authorization credentials to the request
request.setAuthType(entry.getAuthType());
request.setUserPrincipal(reauthPrincipal);
}
}
}
return reauthenticated;
}
Attempts reauthentication to the given Realm using
the credentials associated with the single sign-on session
identified by argument ssoId.
If reauthentication is successful, the Principal and
authorization type associated with the SSO session will be bound
to the given Request object via calls to
Request.setAuthType() and
Request.setUserPrincipal()
|
protected void register(String ssoId,
Principal principal,
String authType,
String username,
String password) {
if (containerLog.isDebugEnabled())
containerLog.debug("Registering sso id '" + ssoId + "' for user '" +
(principal != null ? principal.getName() : "") + "' with auth type '" + authType + "'");
synchronized (cache) {
cache.put(ssoId, new SingleSignOnEntry(principal, authType,
username, password));
}
}
Register the specified Principal as being associated with the specified
value for the single sign on identifier. |
public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
Remove a lifecycle event listener from this component. |
protected void removeSession(String ssoId,
Session session) {
if (containerLog.isDebugEnabled())
containerLog.debug("Removing session " + session.toString() + " from sso id " +
ssoId );
// Get a reference to the SingleSignOn
SingleSignOnEntry entry = lookup(ssoId);
if (entry == null)
return;
// Remove the inactive session from SingleSignOnEntry
entry.removeSession(session);
// Remove the inactive session from the 'reverse' Map.
synchronized(reverse) {
reverse.remove(session);
}
// If there are not sessions left in the SingleSignOnEntry,
// deregister the entry.
if (entry.findSessions().length == 0) {
deregister(ssoId);
}
}
Remove a single Session from a SingleSignOn. Called when
a session is timed out and no longer active. |
public void sessionEvent(SessionEvent event) {
// We only care about session destroyed events
if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType())
&& (!Session.SESSION_PASSIVATED_EVENT.equals(event.getType())))
return;
// Look up the single session id associated with this session (if any)
Session session = event.getSession();
if (containerLog.isDebugEnabled())
containerLog.debug("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
// of all session associated with the SSO.
if (((session.getMaxInactiveInterval() > 0)
&& (System.currentTimeMillis() - session.getLastAccessedTimeInternal() >=
session.getMaxInactiveInterval() * 1000))
|| (Session.SESSION_PASSIVATED_EVENT.equals(event.getType()))) {
removeSession(ssoId, session);
} else {
// The session was logged out.
// Deregister this single session id, invalidating
// associated sessions
deregister(ssoId);
}
}
Acknowledge the occurrence of the specified event. |
public void setCookieDomain(String cookieDomain) {
if (cookieDomain != null && cookieDomain.trim().length() == 0) {
cookieDomain = null;
}
this.cookieDomain = cookieDomain;
}
Sets the domain to be used for sso cookies. |
public void setRequireReauthentication(boolean required) {
this.requireReauthentication = required;
}
Sets whether each request needs to be reauthenticated (by an
Authenticator downstream in the pipeline) to the security
Realm, 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 Realm
If this property is false (the default), this
Valve 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 Realm of the incoming request.
This property should be set to true if the overall server
configuration requires that the Realm reauthenticate each
request thread. An example of such a configuration would be one where
the Realm 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.
If this property is set to true, 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
reauthenticateFromSSO
method to attempt to reauthenticate the request to the
Realm, using any credentials that were cached with this
Valve.
The default value of this property is false, in order
to maintain backward compatibility with previous versions of Tomcat. |
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;
}
Prepare for the beginning of active use of the public methods of this
component. This method should be called after configure(),
and before any of the public methods of the component are utilized. |
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;
}
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. |
public String toString() {
StringBuffer sb = new StringBuffer("SingleSignOn[");
if (container == null )
sb.append("Container is null");
else
sb.append(container.getName());
sb.append("]");
return (sb.toString());
}
Return a String rendering of this object. |
protected void update(String ssoId,
Principal principal,
String authType,
String username,
String password) {
SingleSignOnEntry sso = lookup(ssoId);
if (sso != null && !sso.getCanReauthenticate()) {
if (containerLog.isDebugEnabled())
containerLog.debug("Update sso id " + ssoId + " to auth type " + authType);
synchronized(sso) {
sso.updateCredentials(principal, authType, username, password);
}
}
}
Updates any SingleSignOnEntry found under key
ssoId with the given authentication data.
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.
NOTE: Only updates the SSO entry if a call to
SingleSignOnEntry.getCanReauthenticate() returns
false; otherwise, it is assumed that the SSO entry already
has sufficient information to allow reauthentication and that no update
is needed. |