Search in sources :

Example 56 with SessionException

use of com.sun.identity.plugin.session.SessionException 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 57 with SessionException

use of com.sun.identity.plugin.session.SessionException in project OpenAM by OpenRock.

the class IDPSingleLogout method initiateLogoutRequest.

/**
     * Parses the request parameters and initiates the Logout
     * Request to be sent to the SP.
     *
     * @param request the HttpServletRequest.
     * @param response the HttpServletResponse.
     * @param out the print writer for writing out presentation
     * @param binding binding used for this request.
     * @param paramsMap Map of all other parameters.
     *       Following parameters names with their respective
     *       String values are allowed in this paramsMap.
     *       "RelayState" - the target URL on successful Single Logout
     *       "Destination" - A URI Reference indicating the address to
     *                       which the request has been sent.
     *       "Consent" - Specifies a URI a SAML defined identifier
     *                   known as Consent Identifiers.
     *       "Extension" - Specifies a list of Extensions as list of
     *                   String objects.
     * @throws SAML2Exception if error initiating request to SP.
     */
public static void initiateLogoutRequest(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String binding, Map paramsMap) throws SAML2Exception {
    if (debug.messageEnabled()) {
        debug.message("in initiateLogoutRequest");
        debug.message("binding : " + binding);
        debug.message("logoutAll : " + (String) paramsMap.get(SAML2Constants.LOGOUT_ALL));
        debug.message("paramsMap : " + paramsMap);
    }
    boolean logoutall = false;
    String logoutAllValue = (String) paramsMap.get(SAML2Constants.LOGOUT_ALL);
    if ((logoutAllValue != null) && logoutAllValue.equalsIgnoreCase("true")) {
        logoutall = true;
    }
    String metaAlias = (String) paramsMap.get(SAML2Constants.IDP_META_ALIAS);
    try {
        Object session = sessionProvider.getSession(request);
        String sessUser = sessionProvider.getPrincipalName(session);
        if (session == null) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullSSOToken"));
        }
        if (metaAlias == null) {
            String[] values = sessionProvider.getProperty(session, SAML2Constants.IDP_META_ALIAS);
            if (values != null && values.length != 0) {
                metaAlias = values[0];
            }
        }
        if (metaAlias == null) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullIDPMetaAlias"));
        }
        paramsMap.put(SAML2Constants.METAALIAS, metaAlias);
        String realm = SAML2Utils.getRealm(SAML2MetaUtils.getRealmByMetaAlias(metaAlias));
        String idpEntityID = sm.getEntityByMetaAlias(metaAlias);
        if (idpEntityID == null) {
            debug.error("Identity Provider ID is missing");
            String[] data = { idpEntityID };
            LogUtil.error(Level.INFO, LogUtil.INVALID_IDP, data, null);
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullIDPEntityID"));
        }
        // clean up session index
        String idpSessionIndex = IDPSSOUtil.getSessionIndex(session);
        if (idpSessionIndex == null) {
            if (debug.messageEnabled()) {
                debug.message("No SP session participant(s)");
            }
            MultiProtocolUtils.invalidateSession(session, request, response, SingleLogoutManager.SAML2);
            return;
        }
        // then send the request to the original server
        if (!SAML2FailoverUtils.isSAML2FailoverEnabled() && isMisroutedRequest(request, response, out, session)) {
            return;
        } else {
            if (debug.messageEnabled()) {
                debug.message("IDPSingleLogout.initiateLogoutRequest: " + "SAML2 Failover will be attempted. Be sure SFO is " + "properly configured or the attempt will fail");
            }
        }
        IDPSession idpSession = IDPCache.idpSessionsByIndices.get(idpSessionIndex);
        if (idpSession == null) {
            if (debug.messageEnabled()) {
                debug.message("IDPSLO.initiateLogoutRequest: " + "IDP Session with session index " + idpSessionIndex + " already removed.");
            }
            try {
                if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                    SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
                }
            } catch (SAML2TokenRepositoryException se) {
                debug.error("IDPSingleLogout.initiateLogoutReq: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
            }
            IDPCache.authnContextCache.remove(idpSessionIndex);
            MultiProtocolUtils.invalidateSession(session, request, response, SingleLogoutManager.SAML2);
            return;
        }
        if (debug.messageEnabled()) {
            debug.message("idpSessionIndex=" + idpSessionIndex);
        }
        List<NameIDandSPpair> list = idpSession.getNameIDandSPpairs();
        int n = list.size();
        if (debug.messageEnabled()) {
            debug.message("IDPSingleLogout.initiateLogoutReq:" + " NameIDandSPpairs=" + list + ", size=" + n);
        }
        if (n == 0) {
            if (debug.messageEnabled()) {
                debug.message("No SP session participant(s)");
            }
            IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
            if ((agent != null) && agent.isRunning() && (saml2Svc != null)) {
                saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
            }
            try {
                if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                    SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
                }
            } catch (SAML2TokenRepositoryException se) {
                debug.error("IDPSingleLogout.initiateLogoutReq: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
            }
            IDPCache.authnContextCache.remove(idpSessionIndex);
            MultiProtocolUtils.invalidateSession(session, request, response, SingleLogoutManager.SAML2);
            return;
        }
        String relayState = (String) paramsMap.get(SAML2Constants.RELAY_STATE);
        // Validate the RelayState URL.
        SAML2Utils.validateRelayStateURL(realm, idpEntityID, relayState, SAML2Constants.IDP_ROLE);
        int soapFailCount = 0;
        idpSession.setOriginatingLogoutRequestBinding(binding);
        for (int i = 0; i < n; i++) {
            NameIDandSPpair pair = list.remove(0);
            removeTransientNameIDFromCache(pair.getNameID());
            String spEntityID = pair.getSPEntityID();
            if (debug.messageEnabled()) {
                debug.message("IDPSingleLogout.initLogoutReq: processing spEntityID " + spEntityID);
            }
            List extensionsList = LogoutUtil.getExtensionsList(paramsMap);
            List<SingleLogoutServiceElement> slosList = getSPSLOServiceEndpoints(realm, spEntityID);
            // get IDP entity config in case of SOAP, for basic auth info
            SPSSOConfigElement spConfig = sm.getSPSSOConfig(realm, spEntityID);
            if (logoutall == true) {
                idpSessionIndex = null;
            }
            SingleLogoutServiceElement logoutEndpoint = LogoutUtil.getMostAppropriateSLOServiceLocation(slosList, idpSession.getOriginatingLogoutRequestBinding());
            if (logoutEndpoint == null) {
                continue;
            }
            StringBuffer requestID = null;
            try {
                requestID = LogoutUtil.doLogout(metaAlias, spEntityID, extensionsList, logoutEndpoint, relayState, idpSessionIndex, 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 requestIDStr = requestID.toString();
            String bindingUsed = logoutEndpoint.getBinding();
            if (debug.messageEnabled()) {
                debug.message("\nIDPSLO.requestIDStr = " + requestIDStr + "\nbinding = " + bindingUsed);
            }
            if (!requestIDStr.isEmpty() && (bindingUsed.equals(SAML2Constants.HTTP_REDIRECT) || bindingUsed.equals(SAML2Constants.HTTP_POST))) {
                idpSession.setPendingLogoutRequestID(requestIDStr);
                idpSession.setLogoutAll(logoutall);
                Map logoutMap = (Map) paramsMap.get("LogoutMap");
                if (logoutMap != null && !logoutMap.isEmpty()) {
                    IDPCache.logoutResponseCache.put(requestIDStr, (Map) paramsMap.get("LogoutMap"));
                }
                return;
            }
        }
        //requested binding, or SOAP was used for the logout (or the mixture of this two).
        if (logoutall == true) {
            String userID = sessionProvider.getPrincipalName(idpSession.getSession());
            destroyAllTokenForUser(userID, request, response);
        } else {
            MultiProtocolUtils.invalidateSession(idpSession.getSession(), request, response, SingleLogoutManager.SAML2);
            IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
            if (agent != null && agent.isRunning() && saml2Svc != null) {
                saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
            }
            IDPCache.authnContextCache.remove(idpSessionIndex);
        }
        //handling the case when the auth was initiated with HTTP-Redirect, but only SOAP or no SLO endpoint was
        //available, and also the case when the whole logout process was using SOAP binding from the beginning
        int logoutStatus = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
        boolean isMultiProtocol = MultiProtocolUtils.isMultipleProtocolSession(request, SingleLogoutManager.SAML2);
        //TODO: would be nice to actually return the correct message in idpSingleLogoutInit.jsp
        if (soapFailCount == n) {
            if (isMultiProtocol) {
                logoutStatus = SingleLogoutManager.LOGOUT_FAILED_STATUS;
            }
        } else if (soapFailCount > 0) {
            if (isMultiProtocol) {
                logoutStatus = SingleLogoutManager.LOGOUT_PARTIAL_STATUS;
            }
        }
        // processing multi-federation protocol session
        if (isMultiProtocol) {
            Set set = new HashSet();
            set.add(session);
            boolean isSOAPInitiated = binding.equals(SAML2Constants.SOAP) ? true : false;
            int retStat = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
            try {
                debug.message("IDPSingleLogout.initLogReq: MP");
                retStat = SingleLogoutManager.getInstance().doIDPSingleLogout(set, sessUser, request, response, isSOAPInitiated, true, SingleLogoutManager.SAML2, realm, idpEntityID, null, relayState, null, null, logoutStatus);
            } catch (Exception ex) {
                debug.warning("IDPSingleLogout.initiateLoogutReq: MP", ex);
                throw new SAML2Exception(ex.getMessage());
            }
            if (debug.messageEnabled()) {
                debug.message("IDPSingleLogout.initLogoutRequest: " + "SLOManager return status = " + retStat);
            }
            switch(retStat) {
                case SingleLogoutManager.LOGOUT_FAILED_STATUS:
                    throw new SAML2Exception(SAML2Utils.bundle.getString("sloFailed"));
                case SingleLogoutManager.LOGOUT_PARTIAL_STATUS:
                    throw new SAML2Exception(SAML2Utils.bundle.getString("partialLogout"));
                default:
                    break;
            }
        }
    } catch (SAML2MetaException sme) {
        debug.error("Error retreiving metadata", sme);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    } catch (SessionException ssoe) {
        debug.error("SessionException: ", ssoe);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) SPSSOConfigElement(com.sun.identity.saml2.jaxb.entityconfig.SPSSOConfigElement) SessionException(com.sun.identity.plugin.session.SessionException) 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) SingleLogoutServiceElement(com.sun.identity.saml2.jaxb.metadata.SingleLogoutServiceElement) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) HashSet(java.util.HashSet)

Example 58 with SessionException

use of com.sun.identity.plugin.session.SessionException in project OpenAM by OpenRock.

the class IDPSSOUtil method getSubject.

/**
     * Returns a <code>SAML Subject</code> object
     *
     * @param session           the user's session
     * @param authnReq          the <code>AuthnRequest</code> object
     * @param acsURL            the <code>ACS</code> service <code>url</code>
     * @param nameIDFormat      the <code>NameIDFormat</code>
     * @param realm             The realm name
     * @param idpEntityID       the entity id of the identity provider
     * @param recipientEntityID the entity id of the response recipient
     * @param effectiveTime     the effective time of the assertion
     * @param affiliationID     affiliationID for IDP initiated SSO
     * @return the <code>SAML Subject</code> object
     * @throws SAML2Exception if the operation is not successful
     */
private static Subject getSubject(Object session, AuthnRequest authnReq, String acsURL, String nameIDFormat, String realm, String idpEntityID, String recipientEntityID, int effectiveTime, String affiliationID) throws SAML2Exception {
    String classMethod = "IDPSSOUtil.getSubject: ";
    Subject subject = AssertionFactory.getInstance().createSubject();
    boolean ignoreProfile = false;
    String userName = null;
    try {
        userName = sessionProvider.getPrincipalName(session);
        ignoreProfile = SAML2Utils.isIgnoreProfileSet(session);
    } catch (SessionException se) {
        SAML2Utils.debug.error(classMethod + "There was a problem with the session.", se);
        throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
    }
    // allow create is the default
    boolean allowCreate = true;
    String remoteEntityID = null;
    String spNameQualifier = null;
    boolean isAffiliation = false;
    if (authnReq != null) {
        remoteEntityID = authnReq.getIssuer().getValue();
        NameIDPolicy nameIDPolicy = authnReq.getNameIDPolicy();
        if (nameIDPolicy != null) {
            // this will take care of affiliation
            allowCreate = nameIDPolicy.isAllowCreate();
            spNameQualifier = nameIDPolicy.getSPNameQualifier();
            if (spNameQualifier != null && !spNameQualifier.isEmpty()) {
                AffiliationDescriptorType affiDesc = metaManager.getAffiliationDescriptor(realm, spNameQualifier);
                if (affiDesc != null) {
                    if (affiDesc.getAffiliateMember().contains(remoteEntityID)) {
                        isAffiliation = true;
                        remoteEntityID = spNameQualifier;
                    } else {
                        throw new SAML2Exception(SAML2Utils.bundle.getString("spNotAffiliationMember"));
                    }
                }
            } else {
                spNameQualifier = recipientEntityID;
            }
        }
    } else {
        // IDP initialted SSO
        if (affiliationID != null) {
            AffiliationDescriptorType affiDesc = metaManager.getAffiliationDescriptor(realm, affiliationID);
            if (affiDesc == null) {
                throw new SAML2Exception(SAML2Utils.bundle.getString("affiliationNotFound"));
            }
            if (affiDesc.getAffiliateMember().contains(recipientEntityID)) {
                isAffiliation = true;
                remoteEntityID = affiliationID;
                spNameQualifier = affiliationID;
            } else {
                throw new SAML2Exception(SAML2Utils.bundle.getString("spNotAffiliationMember"));
            }
        } else {
            remoteEntityID = recipientEntityID;
            spNameQualifier = recipientEntityID;
        }
    }
    SPSSODescriptorElement spsso = getSPSSODescriptor(realm, recipientEntityID, classMethod);
    if (spsso == null) {
        String[] data = { recipientEntityID };
        LogUtil.error(Level.INFO, LogUtil.SP_METADATA_ERROR, data, null);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
    IDPSSODescriptorElement idpsso = metaManager.getIDPSSODescriptor(realm, idpEntityID);
    if (idpsso == null) {
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, data, null);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
    nameIDFormat = SAML2Utils.verifyNameIDFormat(nameIDFormat, spsso, idpsso);
    boolean isTransient = SAML2Constants.NAMEID_TRANSIENT_FORMAT.equals(nameIDFormat);
    boolean isPersistent = SAML2Constants.PERSISTENT.equals(nameIDFormat);
    NameIDInfo nameIDInfo;
    NameID nameID = null;
    IDPAccountMapper idpAccountMapper = SAML2Utils.getIDPAccountMapper(realm, idpEntityID);
    //Use-cases for NameID persistence:
    //* persistent NameID -> The NameID MUST be stored
    //* transient NameID -> The NameID MUST NOT be stored
    //* ignored user profile mode -> The NameID CANNOT be stored
    //* for any other cases -> The NameID MAY be stored based on customizable logic
    boolean shouldPersistNameID = isPersistent || (!isTransient && !ignoreProfile && idpAccountMapper.shouldPersistNameIDFormat(realm, idpEntityID, remoteEntityID, nameIDFormat));
    if (!isTransient) {
        String userID;
        try {
            userID = 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"));
        }
        if (isPersistent || shouldPersistNameID) {
            nameIDInfo = AccountUtils.getAccountFederation(userID, idpEntityID, remoteEntityID);
            if (nameIDInfo != null) {
                nameID = nameIDInfo.getNameID();
                if (!nameIDFormat.equals(nameID.getFormat())) {
                    AccountUtils.removeAccountFederation(nameIDInfo, userID);
                    DoManageNameID.removeIDPFedSession(remoteEntityID, nameID.getValue());
                    nameID = null;
                }
            }
        }
    }
    if (nameID == null) {
        if (!allowCreate && isPersistent) {
            throw new SAML2InvalidNameIDPolicyException(SAML2Utils.bundle.getString("cannotCreateNameID"));
        }
        nameID = idpAccountMapper.getNameID(session, idpEntityID, spNameQualifier, realm, nameIDFormat);
        SAML2Utils.debug.message(classMethod + " shouldPersistNameID = " + shouldPersistNameID);
        if (shouldPersistNameID && allowCreate) {
            // write federation info into the persistent datastore
            if (SAML2Utils.isDualRole(idpEntityID, realm)) {
                nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID, nameID, SAML2Constants.DUAL_ROLE, false);
            } else {
                nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID, nameID, SAML2Constants.IDP_ROLE, isAffiliation);
            }
            AccountUtils.setAccountFederation(nameIDInfo, userName);
        }
    }
    subject.setNameID(nameID);
    if (isTransient) {
        IDPCache.userIDByTransientNameIDValue.put(nameID.getValue(), userName);
    }
    String inResponseTo = null;
    if (authnReq != null) {
        inResponseTo = authnReq.getID();
    }
    SubjectConfirmation sc = getSubjectConfirmation(inResponseTo, acsURL, effectiveTime);
    if (sc == null) {
        SAML2Utils.debug.error(classMethod + "Unable to get subject confirmation");
        throw new SAML2Exception(SAML2Utils.bundle.getString("noSubjectConfirmation"));
    }
    List list = new ArrayList();
    list.add(sc);
    subject.setSubjectConfirmation(list);
    return subject;
}
Also used : NameIDInfo(com.sun.identity.saml2.common.NameIDInfo) IDPAccountMapper(com.sun.identity.saml2.plugins.IDPAccountMapper) NameIDPolicy(com.sun.identity.saml2.protocol.NameIDPolicy) NameID(com.sun.identity.saml2.assertion.NameID) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) ArrayList(java.util.ArrayList) SessionException(com.sun.identity.plugin.session.SessionException) AffiliationDescriptorType(com.sun.identity.saml2.jaxb.metadata.AffiliationDescriptorType) Subject(com.sun.identity.saml2.assertion.Subject) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SubjectConfirmation(com.sun.identity.saml2.assertion.SubjectConfirmation) List(java.util.List) ArrayList(java.util.ArrayList) SAML2InvalidNameIDPolicyException(com.sun.identity.saml2.common.SAML2InvalidNameIDPolicyException) IDPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)

Example 59 with SessionException

use of com.sun.identity.plugin.session.SessionException 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 60 with SessionException

use of com.sun.identity.plugin.session.SessionException in project OpenAM by OpenRock.

the class DoManageNameID method processManageNameIDRequest.

private static Status processManageNameIDRequest(ManageNameIDRequest mniRequest, String realm, String hostEntityID, String remoteEntityID, String hostRole, String userID) throws Exception {
    String method = "processManageNameIDRequest: ";
    if (debug.messageEnabled()) {
        debug.message(method + "Host EntityID is : " + hostEntityID);
        debug.message(method + "Host role is : " + hostRole);
        debug.message(method + "Realm  is : " + realm);
    }
    NameID nameID = getNameIDFromMNIRequest(mniRequest, realm, hostEntityID, hostRole);
    NameIDInfo oldNameIDInfo = getNameIDInfo(userID, hostEntityID, remoteEntityID, hostRole, realm, nameID.getSPNameQualifier(), true);
    NameID oldNameID = null;
    if (oldNameIDInfo != null) {
        oldNameID = oldNameIDInfo.getNameID();
    }
    if (oldNameID == null) {
        // log manage name id failure
        logError("unknownPrinciapl", LogUtil.UNKNOWN_PRINCIPAL, mniRequest.toXMLString(true, true));
        return SAML2Utils.generateStatus(SAML2Constants.REQUESTER, SAML2Constants.UNKNOWN_PRINCIPAL, null);
    }
    List spFedSessions = null;
    IDPSession idpSession = null;
    // Terminate
    if (hostRole.equalsIgnoreCase(SAML2Constants.IDP_ROLE)) {
        idpSession = removeIDPFedSession(remoteEntityID, oldNameID.getValue());
    } else {
        spFedSessions = (List) SPCache.fedSessionListsByNameIDInfoKey.remove(oldNameIDInfo.getNameIDInfoKey().toValueString());
        if ((agent != null) && agent.isRunning() && (saml2Svc != null)) {
            saml2Svc.setFedSessionCount((long) SPCache.fedSessionListsByNameIDInfoKey.size());
        }
    }
    if (!AccountUtils.removeAccountFederation(oldNameIDInfo, userID)) {
        // log termination failure
        logError("unableToTerminate", LogUtil.UNABLE_TO_TERMINATE, userID);
        return SAML2Utils.generateStatus(SAML2Constants.RESPONDER, SAML2Utils.bundle.getString("unableToTerminate"));
    }
    if (mniRequest.getTerminate()) {
        // log termination success
        logAccess("requestSuccess", LogUtil.SUCCESS_FED_TERMINATION, userID);
        return SAML2Utils.generateStatus(SAML2Constants.SUCCESS, SAML2Utils.bundle.getString("requestSuccess"));
    }
    // newID case
    NewID newID = getNewIDFromMNIRequest(mniRequest, realm, hostEntityID, hostRole);
    boolean isAffiliation = oldNameIDInfo.isAffiliation();
    String spNameQualifier = oldNameID.getSPNameQualifier();
    if (hostRole.equalsIgnoreCase(SAML2Constants.IDP_ROLE)) {
        NameID newNameID = AssertionFactory.getInstance().createNameID();
        newNameID.setValue(oldNameID.getValue());
        newNameID.setNameQualifier(oldNameID.getNameQualifier());
        newNameID.setSPNameQualifier(spNameQualifier);
        newNameID.setFormat(oldNameID.getFormat());
        newNameID.setSPProvidedID(newID.getValue());
        NameIDInfo newNameIDinfo = new NameIDInfo(hostEntityID, (isAffiliation ? spNameQualifier : remoteEntityID), newNameID, SAML2Constants.IDP_ROLE, isAffiliation);
        AccountUtils.setAccountFederation(newNameIDinfo, userID);
        if (idpSession != null) {
            // there are active session using this Name id
            NameIDandSPpair pair = new NameIDandSPpair(newNameID, remoteEntityID);
            synchronized (IDPCache.idpSessionsByIndices) {
                List list = (List) idpSession.getNameIDandSPpairs();
                list.add(pair);
            }
        }
        // log new name id success
        logAccess("requestSuccess", LogUtil.SUCCESS_NEW_NAMEID, userID);
        return SAML2Utils.generateStatus(SAML2Constants.SUCCESS, SAML2Utils.bundle.getString("requestSuccess"));
    }
    // SP ROLE
    NameID newNameID = AssertionFactory.getInstance().createNameID();
    newNameID.setValue(newID.getValue());
    newNameID.setNameQualifier(oldNameID.getNameQualifier());
    newNameID.setSPProvidedID(oldNameID.getSPProvidedID());
    newNameID.setSPNameQualifier(spNameQualifier);
    newNameID.setFormat(oldNameID.getFormat());
    NameIDInfo newNameIDInfo = new NameIDInfo((isAffiliation ? spNameQualifier : hostEntityID), remoteEntityID, newNameID, hostRole, isAffiliation);
    AccountUtils.setAccountFederation(newNameIDInfo, userID);
    if (spFedSessions != null) {
        String newInfoKeyStr = newNameIDInfo.getNameIDInfoKey().toValueString();
        String infoKeyAttribute = AccountUtils.getNameIDInfoKeyAttribute();
        synchronized (spFedSessions) {
            for (Iterator iter = spFedSessions.iterator(); iter.hasNext(); ) {
                SPFedSession spFedSession = (SPFedSession) iter.next();
                spFedSession.info = newNameIDInfo;
                String tokenID = spFedSession.spTokenID;
                try {
                    Object session = sessionProvider.getSession(tokenID);
                    String[] fromToken = sessionProvider.getProperty(session, infoKeyAttribute);
                    if ((fromToken == null) || (fromToken.length == 0) || (fromToken[0] == null) || (fromToken[0].length() == 0)) {
                        String[] values = { newInfoKeyStr };
                        sessionProvider.setProperty(session, infoKeyAttribute, values);
                    } else {
                        if (fromToken[0].indexOf(newInfoKeyStr) == -1) {
                            String[] values = { fromToken[0] + SAML2Constants.SECOND_DELIM + newInfoKeyStr };
                            sessionProvider.setProperty(session, infoKeyAttribute, values);
                        }
                    }
                } catch (SessionException ex) {
                    debug.error("DoManageNameID." + "processManageNameIDRequest:", ex);
                }
            }
        }
        SPCache.fedSessionListsByNameIDInfoKey.put(newInfoKeyStr, spFedSessions);
        if ((agent != null) && agent.isRunning() && (saml2Svc != null)) {
            saml2Svc.setFedSessionCount((long) SPCache.fedSessionListsByNameIDInfoKey.size());
        }
    }
    // log new name id success
    logAccess("requestSuccess", LogUtil.SUCCESS_NEW_NAMEID, userID);
    return SAML2Utils.generateStatus(SAML2Constants.SUCCESS, SAML2Utils.bundle.getString("requestSuccess"));
}
Also used : NewID(com.sun.identity.saml2.protocol.NewID) NameIDInfo(com.sun.identity.saml2.common.NameIDInfo) NameID(com.sun.identity.saml2.assertion.NameID) SessionException(com.sun.identity.plugin.session.SessionException) Iterator(java.util.Iterator) List(java.util.List)

Aggregations

SessionException (com.sun.identity.plugin.session.SessionException)121 SessionProvider (com.sun.identity.plugin.session.SessionProvider)55 List (java.util.List)40 SAML2Exception (com.sun.identity.saml2.common.SAML2Exception)35 IOException (java.io.IOException)28 ArrayList (java.util.ArrayList)28 Set (java.util.Set)24 SAMLException (com.sun.identity.saml.common.SAMLException)23 Iterator (java.util.Iterator)20 HashMap (java.util.HashMap)18 HashSet (java.util.HashSet)18 Map (java.util.Map)18 FSSession (com.sun.identity.federation.services.FSSession)17 SAML2MetaException (com.sun.identity.saml2.meta.SAML2MetaException)17 FSSessionManager (com.sun.identity.federation.services.FSSessionManager)15 FSException (com.sun.identity.federation.common.FSException)13 IDFFMetaException (com.sun.identity.federation.meta.IDFFMetaException)12 SAML2TokenRepositoryException (org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException)11 ServletException (javax.servlet.ServletException)10 DataStoreProviderException (com.sun.identity.plugin.datastore.DataStoreProviderException)9