SessionRequestHandler.java revision 6309b849c2de831a0eaed9c27b5794bed9bd8fd1
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: SessionRequestHandler.java,v 1.9 2009/04/02 04:11:44 ericow Exp $
*
* Portions Copyrighted 2011-2016 ForgeRock AS.
*/
/**
* Responsible for processing a PLL request and routing it to the appropriate handler which will respond to the caller
* the results of the operation.
*
* The operations available from this handler split into two broad categories:
*
* In the first group, the request is targeting either all LOCAL sessions or a single local session identified by another
* request parameter. The session ID in this case is only used to authenticate the operation. That session is not
* expected to be local to this server (although it might). These operations are:
* <ul>
* <li>GetValidSessions</li>
* <li>GetSessionCount</li>
* </ul>
*
* In the second group, the request is targeting a single session identified by a session ID, which is supposed to be
* hosted by this server instance. The session ID is used both as an id for the target session and to authenticate the
* operation (i.e. operations are performed on the callers own session). The operations in this group are:
* <ul>
* <li>GetSession</li>
* <li>Logout</li>
* <li>AddSessionListener</li>
* <li>SetProperty</li>
* <li>DestroySession</li>
* </ul>
*/
public class SessionRequestHandler implements RequestHandler {
private final SessionService sessionService;
private final Debug sessionDebug;
private final SessionServerConfig serverConfig;
private final StatelessSessionManager statelessSessionManager;
private static final SessionServiceURLService SESSION_SERVICE_URL_SERVICE = InjectorHolder.getInstance(SessionServiceURLService.class);
private static final SessionPLLSender sessionPLLSender = InjectorHolder.getInstance(SessionPLLSender.class);
public SessionRequestHandler() {
}
/**
* Understands how to resolve a Token based on its SessionID.
*
* Stateless Sessions by their very nature do not need to be stored in memory, and so
* can be resolved in a different way to Stateful Sessions.
*
* @param sessionID Non null Session ID.
*
* @return Null if no matching Session could be found, otherwise a non null
* Session instance.
*
* @throws SessionException If there was an error resolving the Session.
*/
}
}
}
return rset;
}
private Response processRequest(
final PLLAuditor auditor,
final HttpServletRequest servletRequest) {
try {
// use remote client IP as default RestrictedToken context
this.clientToken = null;
}
try {
}
}
if (sessionDebug.warningEnabled()) {
"SessionRequestHandler.processRequest:"
+ "app token invalid, sending Session response"
+" with Exception");
}
}
}
try {
new RestrictedTokenAction() {
try {
} catch (ForwardSessionRequestException fsre) {
} catch (SessionException se) {
} catch (SessionRequestException se) {
}
}
});
}
} else {
}
}
}
private SessionResponse processSessionRequest(PLLAuditor auditor, SessionRequest req) throws SessionException,
try {
} catch (SessionException se) {
// Log the access attempt without session properties, then continue.
throw se;
}
}
throws SessionException, SessionRequestException {
throw new SessionRequestException(requesterSession.getSessionID(), SessionBundle.getString("noPrivilege"));
}
}
private void verifyValidRequest(SessionRequest req, Session requesterSession) throws SessionException,
try {
req.getPropertyValue());
} catch (SessionException se) {
if (sessionDebug.warningEnabled()) {
}
throw new SessionRequestException(requesterSession.getSessionID(), SessionBundle.getString("noPrivilege"));
}
}
switch (req.getMethodID()) {
break;
case SessionRequest.GetSession:
case SessionRequest.Logout:
case SessionRequest.SetProperty:
case SessionRequest.DestroySession:
break;
default:
throw new SessionRequestException(requesterSession.getSessionID(), SessionBundle.getString("unknownRequestMethod"));
}
}
/**
* Verify that this server is the correct host for the session and the session can be found(or recovered) locally.
* This function will become much simpler with removal of home servers, or possibly no longer be required.
*/
private void verifyTargetSessionIsLocalOrStateless(SessionRequest req, SessionID sid) throws SessionException,
return;
}
try {
throw new ForwardSessionRequestException(
} catch (SessionException se) {
// attempt retry
// proceed with failover
throw se;
} else {
// we have a shot at retrying here
// if it is remote, forward it
// otherwise treat it as a case of local
// case
throw new ForwardSessionRequestException(
}
}
} else {
throw se;
}
}
}
}
}
}
/**
* Request method-specific processing
*/
private SessionResponse processMethod(SessionRequest req, Session requesterSession) throws SessionException {
switch (req.getMethodID()) {
case SessionRequest.GetSession:
try {
// We need to validate the session before creating the sessioninfo to ensure that the
// stateless session hasn't timed out yet, and hasn't been blacklisted either.
+ req.getSessionID());
}
}
res.addSessionInfo(sessionService.getSessionInfo(requesterSession.getSessionID(), req.getResetFlag()));
} catch (SSOException ssoe) {
return handleException(req, requesterSession.getSessionID(), SessionBundle.getString("invalidSessionID"));
}
break;
SearchResults<SessionInfo> infoSearchResults = sessionService.getValidSessions(requesterSession, pattern);
break;
case SessionRequest.DestroySession:
break;
case SessionRequest.Logout:
break;
break;
case SessionRequest.SetProperty:
sessionService.setExternalProperty(this.clientToken, requesterSession.getSessionID(), req.getPropertyName(), req.getPropertyValue());
break;
}
break;
default:
return handleException(req, requesterSession.getSessionID(), SessionBundle.getString("unknownRequestMethod"));
}
return res;
}
try {
} catch (SessionException ignored) {
// Don't audit with session information.
}
}
throws SessionException {
try {
}
}
return sres;
} catch (SessionException se) {
throw se;
throw new SessionException(ex);
}
}
/**
* !!!!! IMPORTANT !!!!! DO NOT REMOVE "sid" FROM
* EXCEPTIONMESSAGE Logic kludge in legacy Agent 2.0
* code will break If it can not find SID value in
* the exception message returned by Session
* Service. This dependency should be eventually
* removed once we migrate customers to a newer
* agent code base or switch to a new version of
* Session Service interface
*/
return response;
}
private class SessionRequestException extends Exception {
private final String responseMessage;
this.responseMessage = responseMessage;
}
return sid;
}
public String getResponseMessage() {
return responseMessage;
}
}
// This exception is not ideal, but will be removed when crosstalk is removed, and allows the code to better be
// refactored at this point in time.
private class ForwardSessionRequestException extends Exception {
private SessionResponse response;
}
public SessionResponse getResponse() {
return response;
}
}
}