Search in sources :

Example 1 with IDPSessionCopy

use of com.sun.identity.saml2.profile.IDPSessionCopy in project OpenAM by OpenRock.

the class IDPSingleLogout method processLogoutRequest.

/**
     * Gets and processes the Single <code>LogoutRequest</code> from SP
     * and return <code>LogoutResponse</code>.
     *
     * @param logoutReq <code>LogoutRequest</code> from SP
     * @param request the HttpServletRequest.
     * @param response the HttpServletResponse.
     * @param binding name of binding will be used for request processing.
     * @param relayState the relay state.
     * @param idpEntityID name of host entity ID.
     * @param realm name of host entity.
     * @param isVerified true if the request is verified already.
     * @return LogoutResponse the target URL on successful
     * <code>LogoutRequest</code>.
     * @throws SAML2Exception if error processing
     *          <code>LogoutRequest</code>.
     */
public static LogoutResponse processLogoutRequest(LogoutRequest logoutReq, HttpServletRequest request, HttpServletResponse response, String binding, String relayState, String idpEntityID, String realm, boolean isVerified) throws SAML2Exception {
    Status status = null;
    String spEntity = logoutReq.getIssuer().getValue();
    Object session = null;
    String tmpStr = request.getParameter("isLBReq");
    boolean isLBReq = (tmpStr == null || !tmpStr.equals("false"));
    try {
        do {
            String requestId = logoutReq.getID();
            SAML2Utils.verifyRequestIssuer(realm, idpEntityID, logoutReq.getIssuer(), requestId);
            List siList = logoutReq.getSessionIndex();
            if (siList == null) {
                debug.error("IDPSingleLogout.processLogoutRequest: " + "session index are null in logout request");
                status = SAML2Utils.generateStatus(SAML2Constants.REQUESTER, "");
                break;
            }
            int numSI = siList.size();
            // TODO : handle list of session index
            Iterator siIter = siList.iterator();
            String sessionIndex = null;
            if (siIter.hasNext()) {
                sessionIndex = (String) siIter.next();
            }
            if (debug.messageEnabled()) {
                debug.message("IDPLogoutUtil.processLogoutRequest: " + "idpEntityID=" + idpEntityID + ", sessionIndex=" + sessionIndex);
            }
            if (sessionIndex == null) {
                // this case won't happen
                // according to the spec: SP has to send at least
                // one sessionIndex, could be multiple (TODO: need
                // to handle that above; but when IDP sends out
                // logout request, it could omit sessionIndex list,
                // which means all sessions on SP side, so SP side
                // needs to care about this case
                debug.error("IDPLogoutUtil.processLogoutRequest: " + "No session index in logout request");
                status = SAML2Utils.generateStatus(SAML2Constants.REQUESTER, "");
                break;
            }
            String remoteServiceURL = null;
            if (isLBReq) {
                // server id is the last two digit of the session index
                String serverId = sessionIndex.substring(sessionIndex.length() - 2);
                if (debug.messageEnabled()) {
                    debug.message("IDPSingleLogout.processLogoutRequest: " + "sessionIndex=" + sessionIndex + ", id=" + serverId);
                }
                // find out remote serice URL based on server id
                remoteServiceURL = SAML2Utils.getRemoteServiceURL(serverId);
            }
            IDPSession idpSession = IDPCache.idpSessionsByIndices.get(sessionIndex);
            if (idpSession == null && SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                // Read from SAML2 Token Repository
                IDPSessionCopy idpSessionCopy = null;
                try {
                    idpSessionCopy = (IDPSessionCopy) SAML2FailoverUtils.retrieveSAML2Token(sessionIndex);
                } catch (SAML2TokenRepositoryException se) {
                    debug.error("IDPSingleLogout.processLogoutRequest: Error while deleting token from " + "SAML2 Token Repository for sessionIndex:" + sessionIndex, se);
                }
                // Copy back to IDPSession
                if (idpSessionCopy != null) {
                    idpSession = new IDPSession(idpSessionCopy);
                } else {
                    SAML2Utils.debug.error("IDPSessionCopy is NULL!!!");
                }
            }
            if (idpSession == null) {
                // peer then we have to route the request.
                if (remoteServiceURL != null) {
                    boolean peerError = false;
                    String remoteLogoutURL = remoteServiceURL + SAML2Utils.removeDeployUri(request.getRequestURI());
                    String queryString = request.getQueryString();
                    if (queryString == null) {
                        remoteLogoutURL = remoteLogoutURL + "?isLBReq=false";
                    } else {
                        remoteLogoutURL = remoteLogoutURL + "?" + queryString + "&isLBReq=false";
                    }
                    LogoutResponse logoutRes = LogoutUtil.forwardToRemoteServer(logoutReq, remoteLogoutURL);
                    if ((logoutRes != null) && !isNameNotFound(logoutRes)) {
                        if ((isSuccess(logoutRes)) && (numSI > 0)) {
                            siList = LogoutUtil.getSessionIndex(logoutRes);
                            if (siList == null || siList.isEmpty()) {
                                peerError = false;
                                break;
                            }
                        }
                    } else {
                        peerError = true;
                    }
                    if (peerError || (siList != null && siList.size() > 0)) {
                        status = PARTIAL_LOGOUT_STATUS;
                        break;
                    } else {
                        status = SUCCESS_STATUS;
                        break;
                    }
                } else {
                    debug.error("IDPLogoutUtil.processLogoutRequest: " + "IDP no longer has this session index " + sessionIndex);
                    status = SAML2Utils.generateStatus(SAML2Constants.RESPONDER, SAML2Utils.bundle.getString("invalidSessionIndex"));
                    break;
                }
            } else {
                // signature.
                if (!isVerified && !LogoutUtil.verifySLORequest(logoutReq, realm, logoutReq.getIssuer().getValue(), idpEntityID, SAML2Constants.IDP_ROLE)) {
                    throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSignInRequest"));
                }
            }
            session = idpSession.getSession();
            // handle external application logout if configured
            BaseConfigType idpConfig = SAML2Utils.getSAML2MetaManager().getIDPSSOConfig(realm, idpEntityID);
            List appLogoutURL = (List) SAML2MetaUtils.getAttributes(idpConfig).get(SAML2Constants.APP_LOGOUT_URL);
            if (debug.messageEnabled()) {
                debug.message("IDPLogoutUtil.processLogoutRequest: " + "external app logout URL= " + appLogoutURL);
            }
            if ((appLogoutURL != null) && (appLogoutURL.size() != 0)) {
                SAML2Utils.postToAppLogout(request, (String) appLogoutURL.get(0), session);
            }
            List<NameIDandSPpair> list = idpSession.getNameIDandSPpairs();
            int n = list.size();
            if (debug.messageEnabled()) {
                debug.message("IDPLogoutUtil.processLogoutRequest: " + "NameIDandSPpair for " + sessionIndex + " is " + list + ", size=" + n);
            }
            NameIDandSPpair pair = null;
            // remove sending SP from the list
            String spIssuer = logoutReq.getIssuer().getValue();
            for (int i = 0; i < n; i++) {
                pair = list.get(i);
                if (pair.getSPEntityID().equals(spIssuer)) {
                    list.remove(i);
                    removeTransientNameIDFromCache(pair.getNameID());
                    break;
                }
            }
            List partners = idpSession.getSessionPartners();
            boolean cleanUp = true;
            if (partners != null && !partners.isEmpty()) {
                cleanUp = false;
            }
            n = list.size();
            if (n == 0) {
                // this is the case where there is no other
                // session participant
                status = destroyTokenAndGenerateStatus(sessionIndex, idpSession.getSession(), request, response, cleanUp);
                if (cleanUp) {
                    IDPCache.idpSessionsByIndices.remove(sessionIndex);
                    if ((agent != null) && agent.isRunning() && (saml2Svc != null)) {
                        saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
                    }
                    if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                        try {
                            SAML2FailoverUtils.deleteSAML2Token(sessionIndex);
                        } catch (SAML2TokenRepositoryException se) {
                            debug.error("IDPSingleLogout.processLogoutRequest: Error while deleting token from " + "SAML2 Token Repository for sessionIndex:" + sessionIndex, se);
                        }
                    }
                    IDPCache.authnContextCache.remove(sessionIndex);
                }
                break;
            }
            //We should save the originally used request binding to make sure the response is sent back using the
            //correct binding.
            idpSession.setOriginatingLogoutRequestBinding(binding);
            // there are other SPs to be logged out
            if (binding.equals(SAML2Constants.HTTP_REDIRECT) || binding.equals(SAML2Constants.HTTP_POST)) {
                idpSession.setOriginatingLogoutRequestID(logoutReq.getID());
                idpSession.setOriginatingLogoutSPEntityID(logoutReq.getIssuer().getValue());
            }
            int soapFailCount = 0;
            for (int i = 0; i < n; i++) {
                pair = list.remove(0);
                removeTransientNameIDFromCache(pair.getNameID());
                String spEntityID = pair.getSPEntityID();
                if (debug.messageEnabled()) {
                    debug.message("IDPSingleLogout.processLogoutRequest: SP for " + sessionIndex + " is " + spEntityID);
                }
                List<SingleLogoutServiceElement> slosList = getSPSLOServiceEndpoints(realm, spEntityID);
                // get IDP entity config in case of SOAP,for basic auth info
                SPSSOConfigElement spConfig = null;
                spConfig = SAML2Utils.getSAML2MetaManager().getSPSSOConfig(realm, spEntityID);
                String uri = request.getRequestURI();
                String metaAlias = SAML2MetaUtils.getMetaAliasByUri(uri);
                HashMap paramsMap = new HashMap();
                paramsMap.put(SAML2Constants.ROLE, SAML2Constants.IDP_ROLE);
                StringBuffer requestID = null;
                SingleLogoutServiceElement logoutEndpoint = LogoutUtil.getMostAppropriateSLOServiceLocation(slosList, idpSession.getOriginatingLogoutRequestBinding());
                if (logoutEndpoint == null) {
                    continue;
                }
                try {
                    requestID = LogoutUtil.doLogout(metaAlias, spEntityID, null, logoutEndpoint, relayState, sessionIndex, pair.getNameID(), request, response, paramsMap, spConfig);
                } catch (SAML2Exception ex) {
                    if (logoutEndpoint.getBinding().equals(SAML2Constants.SOAP)) {
                        debug.error("IDPSingleLogout.initiateLogoutRequest:", ex);
                        soapFailCount++;
                        continue;
                    } else {
                        throw ex;
                    }
                }
                String bindingUsed = logoutEndpoint.getBinding();
                if (bindingUsed.equals(SAML2Constants.HTTP_REDIRECT) || bindingUsed.equals(SAML2Constants.HTTP_POST)) {
                    String requestIDStr = requestID.toString();
                    if (requestIDStr != null && requestIDStr.length() != 0) {
                        idpSession.setPendingLogoutRequestID(requestIDStr);
                    }
                    return null;
                }
            }
            if (soapFailCount == n) {
                throw new SAML2Exception(SAML2Utils.bundle.getString("sloFailed"));
            } else if (soapFailCount > 0) {
                throw new SAML2Exception(SAML2Utils.bundle.getString("partialLogout"));
            }
            spEntity = idpSession.getOriginatingLogoutSPEntityID();
            if (binding.equals(SAML2Constants.HTTP_REDIRECT) || binding.equals(SAML2Constants.HTTP_POST)) {
                sendLastResponse(idpSession, null, request, response, sessionIndex, session, realm, idpEntityID, relayState);
                return null;
            } else {
                // binding is SOAP, generate logout response
                // and send to initiating SP
                status = destroyTokenAndGenerateStatus(sessionIndex, idpSession.getSession(), request, response, true);
                if (cleanUp) {
                    IDPCache.idpSessionsByIndices.remove(sessionIndex);
                    if ((agent != null) && agent.isRunning() && (saml2Svc != null)) {
                        saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
                    }
                    if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                        try {
                            SAML2FailoverUtils.deleteSAML2Token(sessionIndex);
                        } catch (SAML2TokenRepositoryException se) {
                            debug.error("IDPSingleLogout.processLogoutRequest: Error while deleting token from " + "SAML2 Token Repository for sessionIndex:" + sessionIndex, se);
                        }
                    }
                    IDPCache.authnContextCache.remove(sessionIndex);
                }
            }
        } while (false);
    } catch (SessionException ssoe) {
        debug.error("IDPSingleLogout.processLogoutRequest: unable to get meta for ", ssoe);
        status = SAML2Utils.generateStatus(idpEntityID, ssoe.toString());
    } catch (SAML2Exception e) {
        // show throw exception
        e.printStackTrace();
        SAML2Utils.debug.error("DB ERROR!!!");
    }
    // process multi-federation protocol
    boolean isMultiProtocol = false;
    try {
        SessionProvider provider = SessionManager.getProvider();
        if ((session != null) && (provider.isValid(session)) && MultiProtocolUtils.isMultipleProtocolSession(session, SingleLogoutManager.SAML2)) {
            isMultiProtocol = true;
        }
    } catch (SessionException ex) {
    //ignore
    }
    //here we are providing null for remote entity, because it's an unused variable in the method...
    LogoutResponse logRes = LogoutUtil.generateResponse(status, logoutReq.getID(), SAML2Utils.createIssuer(idpEntityID), realm, SAML2Constants.IDP_ROLE, null);
    if (!isMultiProtocol) {
        return logRes;
    } else {
        try {
            Set set = new HashSet();
            set.add(session);
            String sessUser = SessionManager.getProvider().getPrincipalName(session);
            boolean isSOAPInitiated = binding.equals(SAML2Constants.SOAP);
            SingleLogoutServiceElement endpoint = getLogoutResponseEndpoint(realm, spEntity, binding);
            String location = getResponseLocation(endpoint);
            logRes.setDestination(XMLUtils.escapeSpecialCharacters(location));
            debug.message("IDPSingleLogout.processLogReq : call MP");
            int retStat = SingleLogoutManager.getInstance().doIDPSingleLogout(set, sessUser, request, response, isSOAPInitiated, false, SingleLogoutManager.SAML2, realm, idpEntityID, spEntity, relayState, logoutReq.toXMLString(true, true), logRes.toXMLString(true, true), SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS);
            if (retStat != SingleLogoutManager.LOGOUT_REDIRECTED_STATUS) {
                logRes = updateLogoutResponse(logRes, retStat);
                return logRes;
            } else {
                return null;
            }
        } catch (SessionException ex) {
            debug.error("IDPSingleLogout.ProcessLogoutRequest: SP " + "initiated SOAP logout", ex);
            throw new SAML2Exception(ex.getMessage());
        } catch (Exception ex) {
            debug.error("IDPSingleLogout.ProcessLogoutRequest: SP " + "initiated SOAP logout (MP)", ex);
            throw new SAML2Exception(ex.getMessage());
        }
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) SessionException(com.sun.identity.plugin.session.SessionException) BaseConfigType(com.sun.identity.saml2.jaxb.entityconfig.BaseConfigType) SingleLogoutServiceElement(com.sun.identity.saml2.jaxb.metadata.SingleLogoutServiceElement) Iterator(java.util.Iterator) List(java.util.List) SessionProvider(com.sun.identity.plugin.session.SessionProvider) HashSet(java.util.HashSet) Status(com.sun.identity.saml2.protocol.Status) LogoutResponse(com.sun.identity.saml2.protocol.LogoutResponse) SPSSOConfigElement(com.sun.identity.saml2.jaxb.entityconfig.SPSSOConfigElement) SessionException(com.sun.identity.plugin.session.SessionException) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException) IOException(java.io.IOException) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException)

Example 2 with IDPSessionCopy

use of com.sun.identity.saml2.profile.IDPSessionCopy in project OpenAM by OpenRock.

the class IDPSSOUtil method getAssertion.

/**
     * Returns a <code>SAML Assertion</code> object
     *
     * @throws SAML2Exception if the operation is not successful
     * @param request The HTTP request.
     * @param session The user's session object.
     * @param authnReq The <code>AuthnRequest</code> object.
     * @param recipientEntityID The entity ID of the response recipient.
     * @param idpEntityID The entity ID of the identity provider.
     * @param realm The realm name.
     * @param nameIDFormat The <code>NameIDFormat</code>.
     * @param acsURL The <code>ACS</code> service <code>url</code>.
     * @param affiliationID AffiliationID for IDP initiated SSO.
     * @param matchingAuthnContext the <code>AuthnContext</code> used to find authentication type and scheme.
     * @return the <code>SAML Assertion</code> object.
     * @throws SAML2Exception if the operation is not successful.
     */
private static Assertion getAssertion(HttpServletRequest request, Object session, AuthnRequest authnReq, String recipientEntityID, String idpEntityID, String idpMetaAlias, String realm, String nameIDFormat, String acsURL, String affiliationID, AuthnContext matchingAuthnContext) throws SAML2Exception {
    String classMethod = "IDPSSOUtil.getAssertion: ";
    Assertion assertion = AssertionFactory.getInstance().createAssertion();
    String assertionID = SAML2Utils.generateID();
    assertion.setID(assertionID);
    assertion.setVersion(SAML2Constants.VERSION_2_0);
    assertion.setIssueInstant(new Date());
    Issuer issuer = AssertionFactory.getInstance().createIssuer();
    issuer.setValue(idpEntityID);
    assertion.setIssuer(issuer);
    List statementList = new ArrayList();
    NewBoolean isNewSessionIndex = new NewBoolean();
    AuthnStatement authnStatement = null;
    IDPSession idpSession = null;
    String sessionIndex = null;
    String sessionID = sessionProvider.getSessionID(session);
    synchronized (sessionID) {
        authnStatement = getAuthnStatement(request, session, isNewSessionIndex, authnReq, idpEntityID, realm, matchingAuthnContext);
        if (authnStatement == null) {
            return null;
        }
        sessionIndex = authnStatement.getSessionIndex();
        if (isNewSessionIndex.getValue()) {
            if (SAML2Utils.debug.messageEnabled()) {
                SAML2Utils.debug.message(classMethod + "This is a new IDP session with sessionIndex=" + sessionIndex + ", and sessionID=" + sessionID);
            }
            idpSession = (IDPSession) IDPCache.idpSessionsBySessionID.get(sessionProvider.getSessionID(session));
            if (idpSession == null) {
                idpSession = new IDPSession(session);
            }
            // Set the metaAlias in the IDP session object
            idpSession.setMetaAlias(idpMetaAlias);
            IDPCache.idpSessionsByIndices.put(sessionIndex, idpSession);
            if ((agent != null) && agent.isRunning() && (saml2Svc != null)) {
                saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
            }
        } else {
            idpSession = (IDPSession) IDPCache.idpSessionsByIndices.get(sessionIndex);
        }
    }
    if (isNewSessionIndex.getValue()) {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(classMethod + "a new IDP session has been saved in cache, " + "with sessionIndex=" + sessionIndex);
        }
        try {
            sessionProvider.addListener(session, sessionListener);
        } catch (SessionException e) {
            SAML2Utils.debug.error(classMethod + "Unable to add session listener.");
        }
    } else {
        if (idpSession == null && SAML2FailoverUtils.isSAML2FailoverEnabled()) {
            // Read from SAML2 Token Repository
            IDPSessionCopy idpSessionCopy = null;
            try {
                idpSessionCopy = (IDPSessionCopy) SAML2FailoverUtils.retrieveSAML2Token(sessionIndex);
            } catch (SAML2TokenRepositoryException se) {
                SAML2Utils.debug.error(classMethod + "Unable to obtain IDPSessionCopy from the SAML2 Token Repository for sessionIndex:" + sessionIndex, se);
            }
            // Copy back to IDPSession
            if (idpSessionCopy != null) {
                idpSession = new IDPSession(idpSessionCopy);
            } else {
                SAML2Utils.debug.error("IDPSessionCopy is null");
                throw new SAML2Exception(SAML2Utils.bundle.getString("IDPSessionIsNULL"));
            }
        } else if ((idpSession == null) && (!SAML2FailoverUtils.isSAML2FailoverEnabled())) {
            SAML2Utils.debug.error("IDPSession is null; SAML2 failover" + "is disabled");
            throw new SAML2Exception(SAML2Utils.bundle.getString("IDPSessionIsNULL"));
        } else {
            if (SAML2Utils.debug.messageEnabled()) {
                SAML2Utils.debug.message(classMethod + "This is an existing IDP session with sessionIndex=" + sessionIndex + ", and sessionID=" + sessionProvider.getSessionID(idpSession.getSession()));
            }
        }
    }
    statementList.add(authnStatement);
    AttributeStatement attrStatement = getAttributeStatement(session, idpEntityID, recipientEntityID, realm);
    if (attrStatement != null) {
        List attrStatementList = new ArrayList();
        attrStatementList.add(attrStatement);
        assertion.setAttributeStatements(attrStatementList);
    }
    // get the assertion effective time (in seconds)
    int effectiveTime = getEffectiveTime(realm, idpEntityID);
    // get the NotBefore skew (in seconds)
    int notBeforeSkewTime = getNotBeforeSkewTime(realm, idpEntityID);
    // get the subject element
    Subject subject = getSubject(session, authnReq, acsURL, nameIDFormat, realm, idpEntityID, recipientEntityID, effectiveTime, affiliationID);
    // register (spEntityID, nameID) with the sso token
    // for later logout use 
    String spEntityID = null;
    if (authnReq != null) {
        spEntityID = authnReq.getIssuer().getValue();
    } else {
        spEntityID = recipientEntityID;
    }
    NameIDandSPpair pair = new NameIDandSPpair(subject.getNameID(), spEntityID);
    synchronized (IDPCache.idpSessionsByIndices) {
        List<NameIDandSPpair> list = idpSession.getNameIDandSPpairs();
        String id;
        if (authnReq != null) {
            id = authnReq.getIssuer().getValue();
        } else {
            id = spEntityID;
        }
        boolean found = false;
        for (NameIDandSPpair nameIDandSPpair : list) {
            if (nameIDandSPpair.getSPEntityID().equals(id)) {
                found = true;
                break;
            }
        }
        if (!found) {
            list.add(pair);
        }
    }
    assertion.setAuthnStatements(statementList);
    assertion.setSubject(subject);
    Conditions conditions = getConditions(recipientEntityID, notBeforeSkewTime, effectiveTime);
    assertion.setConditions(conditions);
    String discoBootstrapEnabled = getAttributeValueFromIDPSSOConfig(realm, idpEntityID, SAML2Constants.DISCO_BOOTSTRAPPING_ENABLED);
    if ((discoBootstrapEnabled != null) && discoBootstrapEnabled.equalsIgnoreCase("true")) {
        List attrStatementList = assertion.getAttributeStatements();
        if (attrStatementList == null) {
            attrStatementList = new ArrayList();
            assertion.setAttributeStatements(attrStatementList);
        }
        DiscoveryBootstrap bootstrap = new DiscoveryBootstrap(session, subject, authnStatement.getAuthnContext().getAuthnContextClassRef(), spEntityID, realm);
        attrStatementList.add(bootstrap.getBootstrapStatement());
        assertion.setAdvice(bootstrap.getCredentials());
    }
    if (assertionCacheEnabled(realm, idpEntityID)) {
        String userName = null;
        try {
            userName = sessionProvider.getPrincipalName(session);
        } catch (SessionException se) {
            SAML2Utils.debug.error(classMethod + "Unable to get principal name from the session.", se);
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
        }
        String cacheKey = userName.toLowerCase();
        List assertions = (List) IDPCache.assertionCache.get(cacheKey);
        if (assertions == null) {
            synchronized (IDPCache.assertionCache) {
                assertions = (List) IDPCache.assertionCache.get(cacheKey);
                if (assertions == null) {
                    assertions = new ArrayList();
                    IDPCache.assertionCache.put(cacheKey, assertions);
                }
            }
        }
        synchronized (assertions) {
            assertions.add(assertion);
        }
        IDPCache.assertionByIDCache.put(assertionID, assertion);
        if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
            try {
                SAML2FailoverUtils.saveSAML2Token(assertionID, cacheKey, assertion.toXMLString(true, true), conditions.getNotOnOrAfter().getTime() / 1000);
                if (SAML2Utils.debug.messageEnabled()) {
                    SAML2Utils.debug.message(classMethod + "Saving Assertion to SAML2 Token Repository. ID = " + assertionID);
                }
            } catch (SAML2TokenRepositoryException se) {
                SAML2Utils.debug.error(classMethod + "Unable to save Assertion to the SAML2 Token Repository", se);
            }
        }
    }
    //  Save to SAML2 Token Repository
    try {
        if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
            long sessionExpireTime = System.currentTimeMillis() / 1000 + (sessionProvider.getTimeLeft(session));
            SAML2FailoverUtils.saveSAML2TokenWithoutSecondaryKey(sessionIndex, new IDPSessionCopy(idpSession), sessionExpireTime);
        }
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(classMethod + "SAVE IDPSession!");
        }
    } catch (SessionException se) {
        SAML2Utils.debug.error(classMethod + "Unable to get left-time from the session.", se);
        throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
    } catch (SAML2TokenRepositoryException se) {
        SAML2Utils.debug.error(classMethod + "Unable to save IDPSession to the SAML2 Token Repository", se);
    }
    return assertion;
}
Also used : Issuer(com.sun.identity.saml2.assertion.Issuer) EncryptedAssertion(com.sun.identity.saml2.assertion.EncryptedAssertion) Assertion(com.sun.identity.saml2.assertion.Assertion) ArrayList(java.util.ArrayList) NewBoolean(com.sun.identity.saml2.common.NewBoolean) SessionException(com.sun.identity.plugin.session.SessionException) Date(java.util.Date) Subject(com.sun.identity.saml2.assertion.Subject) Conditions(com.sun.identity.saml2.assertion.Conditions) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) AttributeStatement(com.sun.identity.saml2.assertion.AttributeStatement) AuthnStatement(com.sun.identity.saml2.assertion.AuthnStatement) List(java.util.List) ArrayList(java.util.ArrayList) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException)

Example 3 with IDPSessionCopy

use of com.sun.identity.saml2.profile.IDPSessionCopy in project OpenAM by OpenRock.

the class Saml2SessionUpgradeHandler method handleSessionUpgrade.

@Override
public void handleSessionUpgrade(InternalSession oldSession, InternalSession newSession) {
    final String sessionIndex = oldSession.getProperty(SAML2Constants.IDP_SESSION_INDEX);
    if (StringUtils.isNotEmpty(sessionIndex)) {
        final String oldSessionID = oldSession.getID().toString();
        final String newSessionID = newSession.getID().toString();
        final SSOToken oldSSOToken;
        final SSOToken newSSOToken;
        try {
            oldSSOToken = ssoTokenManager.createSSOToken(oldSessionID);
            newSSOToken = ssoTokenManager.createSSOToken(newSessionID);
        } catch (SSOException ssoe) {
            debug.warning("Unable to create an SSOToken for the session ID due to " + ssoe.toString());
            return;
        }
        IDPSession idpSession = IDPCache.idpSessionsByIndices.get(sessionIndex);
        if (idpSession == null) {
            if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                try {
                    final IDPSessionCopy idpSessionCopy = (IDPSessionCopy) SAML2FailoverUtils.retrieveSAML2Token(sessionIndex);
                    if (idpSessionCopy != null) {
                        idpSession = new IDPSession(idpSessionCopy);
                    }
                } catch (SAML2TokenRepositoryException stre) {
                    debug.warning("Unable to retrieve IDPSessionCopy from SAML failover store", stre);
                }
            }
        }
        if (idpSession != null) {
            idpSession.setSession(newSSOToken);
            if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                try {
                    SAML2FailoverUtils.deleteSAML2Token(sessionIndex);
                    long expirationTime = System.currentTimeMillis() / 1000 + newSession.getTimeLeft();
                    SAML2FailoverUtils.saveSAML2TokenWithoutSecondaryKey(sessionIndex, new IDPSessionCopy(idpSession), expirationTime);
                } catch (SAML2TokenRepositoryException stre) {
                    debug.error("Failed to update IDPSession in SAML failover store", stre);
                }
            }
            IDPCache.idpSessionsByIndices.put(sessionIndex, idpSession);
            IDPCache.idpSessionsBySessionID.put(newSessionID, idpSession);
        }
        IDPCache.idpSessionsBySessionID.remove(oldSessionID);
        final String partner = IDPCache.spSessionPartnerBySessionID.remove(oldSessionID);
        if (partner != null) {
            IDPCache.spSessionPartnerBySessionID.put(newSessionID, partner);
        }
        try {
            //We set the sessionIndex to a dummy value so that IDPSessionListener won't try to clear out the caches
            //for the still valid sessionIndex.
            oldSSOToken.setProperty(SAML2Constants.IDP_SESSION_INDEX, "dummy");
        } catch (SSOException ssoe) {
            debug.error("Failed to set IDP Session Index for old session", ssoe);
        }
    }
}
Also used : SSOToken(com.iplanet.sso.SSOToken) IDPSession(com.sun.identity.saml2.profile.IDPSession) SSOException(com.iplanet.sso.SSOException) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException) IDPSessionCopy(com.sun.identity.saml2.profile.IDPSessionCopy)

Aggregations

SAML2TokenRepositoryException (org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException)3 SessionException (com.sun.identity.plugin.session.SessionException)2 SAML2Exception (com.sun.identity.saml2.common.SAML2Exception)2 List (java.util.List)2 SSOException (com.iplanet.sso.SSOException)1 SSOToken (com.iplanet.sso.SSOToken)1 SessionProvider (com.sun.identity.plugin.session.SessionProvider)1 Assertion (com.sun.identity.saml2.assertion.Assertion)1 AttributeStatement (com.sun.identity.saml2.assertion.AttributeStatement)1 AuthnStatement (com.sun.identity.saml2.assertion.AuthnStatement)1 Conditions (com.sun.identity.saml2.assertion.Conditions)1 EncryptedAssertion (com.sun.identity.saml2.assertion.EncryptedAssertion)1 Issuer (com.sun.identity.saml2.assertion.Issuer)1 Subject (com.sun.identity.saml2.assertion.Subject)1 NewBoolean (com.sun.identity.saml2.common.NewBoolean)1 BaseConfigType (com.sun.identity.saml2.jaxb.entityconfig.BaseConfigType)1 SPSSOConfigElement (com.sun.identity.saml2.jaxb.entityconfig.SPSSOConfigElement)1 SingleLogoutServiceElement (com.sun.identity.saml2.jaxb.metadata.SingleLogoutServiceElement)1 SAML2MetaException (com.sun.identity.saml2.meta.SAML2MetaException)1 IDPSession (com.sun.identity.saml2.profile.IDPSession)1