@Override public boolean action(InternalSession is, Map<String, Long> sessions) { String nextExpiringSessionID = null; long smallestExpTime = Long.MAX_VALUE; for (Map.Entry<String, Long> entry : sessions.entrySet()) { String sid = entry.getKey(); long expirationTime = entry.getValue(); if (expirationTime < smallestExpTime) { smallestExpTime = expirationTime; nextExpiringSessionID = sid; } } if (nextExpiringSessionID != null) { SessionID sessID = new SessionID(nextExpiringSessionID); try { Session s = sessionCache.getSession(sessID); s.destroySession(s); } catch (SessionException e) { if (debug.messageEnabled()) { debug.message("Failed to destroy the next " + "expiring session.", e); } // deny the session activation request // in this case return true; } } return false; }
/** * Perform a remote setProperty on the Session using the remote Service URL. * * <p>{@inheritDoc} */ public void setProperty(Session session, String name, String value) throws SessionException { if (debug.messageEnabled()) { debug.message(MessageFormat.format("Remote setProperty {0} {1}={2}", session, name, value)); } SessionID sessionID = session.getID(); SessionRequest sreq = new SessionRequest(SessionRequest.SetProperty, sessionID.toString(), false); sreq.setPropertyName(name); sreq.setPropertyValue(value); if (SystemProperties.isServerMode() && InternalSession.isProtectedProperty(name)) { try { SSOToken admSSOToken = SessionUtils.getAdminToken(); sreq.setRequester(RestrictedTokenContext.marshal(admSSOToken)); } catch (SSOException e) { throw new SessionException(e); } catch (Exception e) { throw new SessionException(e); } if (debug.messageEnabled()) { debug.message( "Session.setProperty: " + "added admSSOToken in sreq to set " + "externalProtectedProperty in remote server"); } } requests.sendRequestWithRetry(session.getSessionServiceURL(), sreq, session); }
/** * Performs a logout operation by making a remote request based on the Sessions service URL. * * @param session Session to logout. */ public void logout(Session session) throws SessionException { if (debug.messageEnabled()) { debug.message(MessageFormat.format("Remote logout {0}", session.getID().toString())); } SessionRequest sreq = new SessionRequest(SessionRequest.Logout, session.getID().toString(), false); requests.sendRequestWithRetry(session.getSessionServiceURL(), sreq, session); }
/** * Destroys the Session via the Session remote service URL. * * @param requester {@inheritDoc} * @param session {@inheritDoc} * @throws SessionException {@inheritDoc} */ public void destroy(Session requester, Session session) throws SessionException { if (debug.messageEnabled()) { debug.message(MessageFormat.format("Remote destroy {0}", session)); } SessionRequest sreq = new SessionRequest(SessionRequest.DestroySession, requester.getID().toString(), false); sreq.setDestroySessionID(session.getID().toString()); requests.sendRequestWithRetry(session.getSessionServiceURL(), sreq, session); }
/** * Returns URL encoded with the cookie Value (SSOToken ID) if cookies are not support. Throws an * SSOException in case of an error. * * <p>The cookie Value is written in the URL based on the encodingScheme specified. The Cookie * Value could be written as path info separated by either a "/" OR ";" or as a query string. * * <p>If the encoding scheme is SLASH then the cookie value would be written in the URL as extra * path info in the following format: * * <pre> * protocol://server:port/servletpath/<cookieName>=<cookieValue>? * queryString * </pre> * * <p>Note that this format works only if the path is a servlet, if a a jsp file is specified then * webcontainers return with "File Not found" error. To rewrite links which are JSP files with * cookie value use the SEMICOLON OR QUERY encoding scheme. * * <p>If the encoding scheme is SEMICOLON then the cookie value would be written in the URL as * extra path info in the following format: * * <pre> * protocol://server:port/path;<cookieName=cookieValue>?queryString * </pre> * * Note that this is not supported in the servlet specification and some web containers do not * support this. * * <p>If the encoding scheme is QUERY then the cookie value would be written in the URL in the * following format: * * <pre> * protocol://server:port/path?<cookieName>=<cookieValue> * protocol://server:port/path?queryString& * <cookieName>=<cookieValue> * </pre> * * <p>This is the default and OpenSSO always encodes in this format unless otherwise specified. If * the URL passed in has query parameter then entity escaping of ampersand will be done before * appending the cookie if the escape is true.Only the ampersand before appending cookie parameter * will be entity escaped. * * <p> * * @param ssoToken Single Sign Token which contains the session string. * @param url the URL to be encoded * @param encodingScheme possible values are <code>QUERY</code>, <code>SLASH</code>, <code> * SEMICOLON</code>. * @param escape <code>true</code> to escape ampersand when appending the Single Sign On Token ID * to request query string. * @return encoded URL with cookie value (session ID) based on the encoding scheme. * @exception SSOException if URL cannot be encoded. */ public static String encodeURL( SSOToken ssoToken, String url, short encodingScheme, boolean escape) throws SSOException { String encodedURL = url; try { SSOTokenID ssoTokenId = ssoToken.getTokenID(); SessionID sessionID = new SessionID(ssoTokenId.toString()); Session session = Session.getSession(sessionID); encodedURL = session.encodeURL(url, encodingScheme, escape); } catch (Exception e) { debug.message("Exception encoding URL ", e); throw new SSOException(e); } return encodedURL; }
/** * @param session The Session to update. * @param reset If true, then update the last modified timestamp of the Session. * @return * @throws SessionException */ public SessionInfo refresh(Session session, boolean reset) throws SessionException { SessionID sessionID = session.getID(); if (debug.messageEnabled()) { debug.message( MessageFormat.format( "Remote fetch SessionInfo for {0}\n" + "Reset: {1}", sessionID, reset)); } SessionRequest sreq = new SessionRequest(SessionRequest.GetSession, sessionID.toString(), reset); SessionResponse sres = requests.sendRequestWithRetry(session.getSessionServiceURL(), sreq, session); if (sres.getException() != null) { throw new SessionException(SessionBundle.rbName, INVALID_SESSION_STATE, null); } List<SessionInfo> infos = sres.getSessionInfo(); if (infos.size() != 1) { throw new SessionException(SessionBundle.rbName, UNEXPECTED_SESSION, null); } return infos.get(0); }
private void initAuthSessions() throws SSOException, SessionException { if (authSession == null) { authSession = getSS().getAuthenticationSession(defaultOrg, null); if (authSession == null) { debug.error("AuthD failed to get auth session"); throw new SessionException(BUNDLE_NAME, "gettingSessionFailed", null); } String clientID = authSession.getClientID(); authSession.setProperty("Principal", clientID); authSession.setProperty("Organization", defaultOrg); authSession.setProperty("Host", authSession.getID().getSessionServer()); DN dn = new DN(clientID); if (dn.isDN()) { String[] tokens = dn.explodeDN(true); String id = "id=" + tokens[0] + ",ou=user," + ServiceManager.getBaseDN(); authSession.setProperty(Constants.UNIVERSAL_IDENTIFIER, id); } SSOTokenManager ssoManager = SSOTokenManager.getInstance(); ssoAuthSession = ssoManager.createSSOToken(authSession.getID().toString()); } }
/** * This the main method of this servlet which takes in the request opens a URLConnection to the * CDCServlet endpoint in the OpenAM, and tunnels the request content to it. It parses the * Response received and if the HTTP_STATUS is "HTTP_OK" or "HTTP_MOVED_TEMP" POSTs the received * Liberty Authn Response to the goto URL specified in the original request. */ private void sendAuthnRequest( HttpServletRequest request, HttpServletResponse response, SSOToken token) throws ServletException, IOException { SessionID sessid = new SessionID(request); URL CDCServletURL = null; URL sessionServiceURL = null; try { sessionServiceURL = Session.getSessionServiceURL(sessid); } catch (SessionException se) { debug.error( "CDCClientServlet.sendAuthnRequest: Cannot locate" + " OpenAM instance to forward to.", se); showError(response, "Cannot locate OpenAM instance to forward to"); } if (sessionServiceURL == null) { showError(response, "Cannot locate OpenAM instance to forward to"); } // replace "sessionservice" by cdcservlet in obtained URL // we use naming so that we get the URL of the exact server // where the session is located and get the right deployment // descriptor. String sessionServiceURLString = sessionServiceURL.toString(); int serviceNameIndex = sessionServiceURLString.lastIndexOf( "/", sessionServiceURLString.length() - 2); // avoiding trailing "/" // if any StringBuilder buffer = new StringBuilder(150); buffer .append(sessionServiceURLString.substring(0, serviceNameIndex)) .append(CDCURI) .append(QUESTION_MARK) .append(request.getQueryString()); // add query string to // CDCServletURL CDCServletURL = new URL(buffer.toString()); // save the go to URL of the agent side to ultimately // POST to. try { HttpURLConnection connection = HttpURLConnectionManager.getConnection(CDCServletURL); connection.setRequestMethod("GET"); connection.setRequestProperty("Content-Type", "text/html;charset=UTF-8"); connection.setDoOutput(true); connection.setUseCaches(false); // replay cookies String strCookies = getCookiesFromRequest(request); if (strCookies != null) { if (debug.messageEnabled()) { debug.message("CDCClientServlet.sendAuthnRequest:Setting " + "cookies = " + strCookies); } connection.setRequestProperty("Cookie", strCookies); } // dont wish to follow redirect to agent, since // the response needs to go via the CDCClientServlet. HttpURLConnection.setFollowRedirects(false); // Receiving input from CDCServlet on the AM server instance if (debug.messageEnabled()) { debug.message( "CDCClientServlet.sendAuthnRequest:Getting " + "response back from " + CDCServletURL); debug.message( "CDCClientServlet.sendAuthnRequest:Response " + "Code " + connection.getResponseCode()); debug.message( "CDCClientServlet.sendAuthnRequest:Response " + "Message= " + connection.getResponseMessage()); } // Check response code if ((connection.getResponseCode() == HttpURLConnection.HTTP_OK) || (connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP)) { /** * Read the response back from CDCServlet, got a redirect since this response contains the * "LARES" ( Liberty authn response, which needs to be posted back to the dest url (agent). */ StringBuilder inBuf = new StringBuilder(); BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); int len; char[] buf = new char[1024]; while ((len = in.read(buf, 0, buf.length)) != -1) { inBuf.append(buf, 0, len); } String inString = inBuf.toString(); if (debug.messageEnabled()) { debug.message( "CDCClientServlet.sendAuthnRequest:" + "Received response data = " + inString); } // put the received Liberty Auth Response // in the servlet's response. sendAuthnResponse(request, response, inString); } else { debug.error("CDCClientServlet.sendAuthnRequest: Response " + "code NOT OK/MOVED_TEMP "); showError( response, "ERROR: Received HTTP error code " + connection.getResponseCode() + " from " + CDCServletURL); } } catch (ConnectException ce) { // Debug the exception if (debug.warningEnabled()) { debug.warning( "CDCClientServlet.sendAuthnRequest: " + "Connection Exception to " + CDCServletURL, ce); } showError( response, "Could not connect to CDCServlet at " + CDCServletURL + ":" + ce.getMessage()); } }