Search in sources :

Example 1 with IDPAuthnContextMapper

use of com.sun.identity.saml2.plugins.IDPAuthnContextMapper in project OpenAM by OpenRock.

the class UtilProxySAMLAuthenticator method authenticate.

@Override
public void authenticate() throws FederatedSSOException, IOException {
    final String classMethod = "UtilProxySAMLAuthenticator.authenticate: ";
    SPSSODescriptorElement spSSODescriptor = null;
    String preferredIDP;
    // There is no reqID, this is the first time that we pass here.
    String binding = SAML2Constants.HTTP_REDIRECT;
    if (request.getMethod().equals("POST")) {
        binding = SAML2Constants.HTTP_POST;
    }
    data.setAuthnRequest(getAuthnRequest(request, isFromECP, binding));
    if (data.getAuthnRequest() == null) {
        throw new ClientFaultException(data.getIdpAdapter(), INVALID_SAML_REQUEST);
    }
    data.getEventAuditor().setRequestId(data.getRequestID());
    data.setSpEntityID(data.getAuthnRequest().getIssuer().getValue());
    try {
        logAccess(isFromECP ? LogUtil.RECEIVED_AUTHN_REQUEST_ECP : LogUtil.RECEIVED_AUTHN_REQUEST, Level.INFO, data.getSpEntityID(), data.getIdpMetaAlias(), data.getAuthnRequest().toXMLString());
    } catch (SAML2Exception saml2ex) {
        SAML2Utils.debug.error(classMethod, saml2ex);
        throw new ClientFaultException(data.getIdpAdapter(), INVALID_SAML_REQUEST, saml2ex.getMessage());
    }
    if (!SAML2Utils.isSourceSiteValid(data.getAuthnRequest().getIssuer(), data.getRealm(), data.getIdpEntityID())) {
        SAML2Utils.debug.warning("{} Issuer in Request is not valid.", classMethod);
        throw new ClientFaultException(data.getIdpAdapter(), INVALID_SAML_REQUEST);
    }
    // verify the signature of the query string if applicable
    IDPSSODescriptorElement idpSSODescriptor;
    try {
        idpSSODescriptor = IDPSSOUtil.metaManager.getIDPSSODescriptor(data.getRealm(), data.getIdpEntityID());
    } catch (SAML2MetaException sme) {
        SAML2Utils.debug.error(classMethod + "Unable to get IDP SSO Descriptor from meta.");
        throw new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
    }
    try {
        spSSODescriptor = IDPSSOUtil.metaManager.getSPSSODescriptor(data.getRealm(), data.getSpEntityID());
    } catch (SAML2MetaException sme) {
        SAML2Utils.debug.error(classMethod + "Unable to get SP SSO Descriptor from meta.");
        SAML2Utils.debug.error(classMethod, sme);
    }
    if (isFromECP || idpSSODescriptor.isWantAuthnRequestsSigned() || (spSSODescriptor != null && spSSODescriptor.isAuthnRequestsSigned())) {
        // need to verify the query string containing authnRequest
        if (StringUtils.isBlank(data.getSpEntityID())) {
            throw new ClientFaultException(data.getIdpAdapter(), INVALID_SAML_REQUEST);
        }
        if (spSSODescriptor == null) {
            SAML2Utils.debug.error(classMethod + "Unable to get SP SSO Descriptor from meta.");
            throw new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
        }
        Set<X509Certificate> certificates = KeyUtil.getVerificationCerts(spSSODescriptor, data.getSpEntityID(), SAML2Constants.SP_ROLE);
        try {
            boolean isSignatureOK;
            if (isFromECP) {
                isSignatureOK = data.getAuthnRequest().isSignatureValid(certificates);
            } else {
                if ("POST".equals(request.getMethod())) {
                    isSignatureOK = data.getAuthnRequest().isSignatureValid(certificates);
                } else {
                    isSignatureOK = QuerySignatureUtil.verify(request.getQueryString(), certificates);
                }
            }
            if (!isSignatureOK) {
                SAML2Utils.debug.error(classMethod + "authn request verification failed.");
                throw new ClientFaultException(data.getIdpAdapter(), "invalidSignInRequest");
            }
            // In ECP profile, sp doesn't know idp.
            if (!isFromECP) {
                // verify Destination
                List ssoServiceList = idpSSODescriptor.getSingleSignOnService();
                String ssoURL = SPSSOFederate.getSSOURL(ssoServiceList, binding);
                if (!SAML2Utils.verifyDestination(data.getAuthnRequest().getDestination(), ssoURL)) {
                    SAML2Utils.debug.error(classMethod + "authn request destination verification failed.");
                    throw new ClientFaultException(data.getIdpAdapter(), "invalidDestination");
                }
            }
        } catch (SAML2Exception se) {
            SAML2Utils.debug.error(classMethod + "authn request verification failed.", se);
            throw new ClientFaultException(data.getIdpAdapter(), "invalidSignInRequest");
        }
        SAML2Utils.debug.message("{} authn request signature verification is successful.", classMethod);
    }
    SAML2Utils.debug.message("{} request id= {}", classMethod, data.getRequestID());
    if (data.getRequestID() == null) {
        SAML2Utils.debug.error(classMethod + "Request id is null");
        throw new ClientFaultException(data.getIdpAdapter(), "InvalidSAMLRequestID");
    }
    if (isFromECP) {
        try {
            IDPECPSessionMapper idpECPSessonMapper = IDPSSOUtil.getIDPECPSessionMapper(data.getRealm(), data.getIdpEntityID());
            data.setSession(idpECPSessonMapper.getSession(request, response));
        } catch (SAML2Exception se) {
            SAML2Utils.debug.message("Unable to retrieve user session.", classMethod);
        }
    } else {
        // get the user sso session from the request
        try {
            data.setSession(SessionManager.getProvider().getSession(request));
        } catch (SessionException se) {
            SAML2Utils.debug.message("{} Unable to retrieve user session.", classMethod);
        }
    }
    if (null != data.getSession()) {
        data.getEventAuditor().setAuthTokenId(data.getSession());
    }
    // will not trigger this adapter call
    if (preSingleSignOn(request, response, data)) {
        return;
    }
    // End of adapter invocation
    IDPAuthnContextMapper idpAuthnContextMapper = null;
    try {
        idpAuthnContextMapper = IDPSSOUtil.getIDPAuthnContextMapper(data.getRealm(), data.getIdpEntityID());
    } catch (SAML2Exception sme) {
        SAML2Utils.debug.error(classMethod, sme);
    }
    if (idpAuthnContextMapper == null) {
        SAML2Utils.debug.error(classMethod + "Unable to get IDPAuthnContextMapper from meta.");
        throw new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
    }
    IDPAuthnContextInfo idpAuthnContextInfo = null;
    try {
        idpAuthnContextInfo = idpAuthnContextMapper.getIDPAuthnContextInfo(data.getAuthnRequest(), data.getIdpEntityID(), data.getRealm());
    } catch (SAML2Exception sme) {
        SAML2Utils.debug.error(classMethod, sme);
    }
    if (idpAuthnContextInfo == null) {
        SAML2Utils.debug.message("{} Unable to find valid AuthnContext. Sending error Response.", classMethod);
        try {
            Response res = SAML2Utils.getErrorResponse(data.getAuthnRequest(), SAML2Constants.REQUESTER, SAML2Constants.NO_AUTHN_CONTEXT, null, data.getIdpEntityID());
            StringBuffer returnedBinding = new StringBuffer();
            String acsURL = IDPSSOUtil.getACSurl(data.getSpEntityID(), data.getRealm(), data.getAuthnRequest(), request, returnedBinding);
            String acsBinding = returnedBinding.toString();
            IDPSSOUtil.sendResponse(request, response, out, acsBinding, data.getSpEntityID(), data.getIdpEntityID(), data.getIdpMetaAlias(), data.getRealm(), data.getRelayState(), acsURL, res, data.getSession());
        } catch (SAML2Exception sme) {
            SAML2Utils.debug.error(classMethod, sme);
            throw new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
        }
        return;
    }
    // get the relay state query parameter from the request
    data.setRelayState(request.getParameter(SAML2Constants.RELAY_STATE));
    data.setMatchingAuthnContext(idpAuthnContextInfo.getAuthnContext());
    if (data.getSession() == null) {
        // the user has not logged in yet, redirect to auth
        redirectToAuth(spSSODescriptor, binding, idpAuthnContextInfo, data);
    } else {
        SAML2Utils.debug.message("{} There is an existing session", classMethod);
        // Let's verify that the realm is the same for the user and the IdP
        boolean isValidSessionInRealm = IDPSSOUtil.isValidSessionInRealm(data.getRealm(), data.getSession());
        String sessionIndex = IDPSSOUtil.getSessionIndex(data.getSession());
        boolean sessionUpgrade = false;
        if (isValidSessionInRealm) {
            sessionUpgrade = isSessionUpgrade(idpAuthnContextInfo, data.getSession());
            SAML2Utils.debug.message("{} IDP Session Upgrade is : {}", classMethod, sessionUpgrade);
        }
        // Holder for any exception encountered while redirecting for authentication:
        FederatedSSOException redirectException = null;
        if (sessionUpgrade || !isValidSessionInRealm || ((Boolean.TRUE.equals(data.getAuthnRequest().isForceAuthn())) && (!Boolean.TRUE.equals(data.getAuthnRequest().isPassive())))) {
            // sessionIndex
            if (sessionIndex != null && sessionIndex.length() != 0) {
                // Save the original IDP Session
                IDPSession oldIDPSession = IDPCache.idpSessionsByIndices.get(sessionIndex);
                if (oldIDPSession != null) {
                    IDPCache.oldIDPSessionCache.put(data.getRequestID(), oldIDPSession);
                } else {
                    SAML2Utils.debug.error(classMethod + "The old SAML2 session  was not found in the idp session " + "by indices cache");
                }
            }
            // Save the new requestId and AuthnRequest
            IDPCache.authnRequestCache.put(data.getRequestID(), new CacheObject(data.getAuthnRequest()));
            // Save the new requestId and AuthnContext
            IDPCache.idpAuthnContextCache.put(data.getRequestID(), new CacheObject(data.getMatchingAuthnContext()));
            // save if the request was an Session Upgrade case.
            IDPCache.isSessionUpgradeCache.add(data.getRequestID());
            // authenticates
            if (StringUtils.isNotBlank(data.getRelayState())) {
                IDPCache.relayStateCache.put(data.getRequestID(), data.getRelayState());
            }
            // Session upgrade could be requested by asking a greater AuthnContext
            if (isValidSessionInRealm) {
                try {
                    boolean isProxy = IDPProxyUtil.isIDPProxyEnabled(data.getAuthnRequest(), data.getRealm());
                    if (isProxy) {
                        preferredIDP = IDPProxyUtil.getPreferredIDP(data.getAuthnRequest(), data.getIdpEntityID(), data.getRealm(), request, response);
                        if (preferredIDP != null) {
                            if ((SPCache.reqParamHash != null) && (!(SPCache.reqParamHash.containsKey(preferredIDP)))) {
                                // IDP Proxy with configured proxy list
                                SAML2Utils.debug.message("{} IDP to be proxied {}", classMethod, preferredIDP);
                                IDPProxyUtil.sendProxyAuthnRequest(data.getAuthnRequest(), preferredIDP, spSSODescriptor, data.getIdpEntityID(), request, response, data.getRealm(), data.getRelayState(), binding);
                                return;
                            } else {
                                // IDP proxy with introduction cookie
                                Map paramsMap = (Map) SPCache.reqParamHash.get(preferredIDP);
                                paramsMap.put("authnReq", data.getAuthnRequest());
                                paramsMap.put("spSSODescriptor", spSSODescriptor);
                                paramsMap.put("idpEntityID", data.getIdpEntityID());
                                paramsMap.put("realm", data.getRealm());
                                paramsMap.put("relayState", data.getRelayState());
                                paramsMap.put("binding", binding);
                                SPCache.reqParamHash.put(preferredIDP, paramsMap);
                                return;
                            }
                        }
                    }
                //else continue for the local authentication.
                } catch (SAML2Exception re) {
                    SAML2Utils.debug.message("{} Redirecting for the proxy handling error: {}", classMethod, re.getMessage());
                    redirectException = new ServerFaultException(data.getIdpAdapter(), "UnableToRedirectToPreferredIDP", re.getMessage());
                }
            // End of IDP Proxy: Initiate proxying when session upgrade is requested
            }
            // Invoke the IDP Adapter before redirecting to authn
            if (preAuthenticationAdapter(request, response, data)) {
                return;
            }
            //we don't have a session
            try {
                //and they want to authenticate
                if (!Boolean.TRUE.equals(data.getAuthnRequest().isPassive())) {
                    redirectAuthentication(request, response, idpAuthnContextInfo, data, true);
                    return;
                } else {
                    try {
                        //and they want to get into the system with passive auth - response no passive
                        IDPSSOUtil.sendNoPassiveResponse(request, response, out, data.getIdpMetaAlias(), data.getIdpEntityID(), data.getRealm(), data.getAuthnRequest(), data.getRelayState(), data.getSpEntityID());
                    } catch (SAML2Exception sme) {
                        SAML2Utils.debug.error(classMethod, sme);
                        redirectException = new ServerFaultException(data.getIdpAdapter(), METADATA_ERROR);
                    }
                }
            } catch (IOException | SAML2Exception e) {
                SAML2Utils.debug.error(classMethod + "Unable to redirect to authentication.", e);
                sessionUpgrade = false;
                cleanUpCache(data.getRequestID());
                redirectException = new ServerFaultException(data.getIdpAdapter(), "UnableToRedirectToAuth", e.getMessage());
            }
        }
        // generate assertion response
        if (!sessionUpgrade && isValidSessionInRealm) {
            generateAssertionResponse(data);
        }
        if (redirectException != null) {
            throw redirectException;
        }
    }
}
Also used : IDPAuthnContextInfo(com.sun.identity.saml2.plugins.IDPAuthnContextInfo) IDPAuthnContextMapper(com.sun.identity.saml2.plugins.IDPAuthnContextMapper) IDPSession(com.sun.identity.saml2.profile.IDPSession) ServerFaultException(com.sun.identity.saml2.profile.ServerFaultException) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) SessionException(com.sun.identity.plugin.session.SessionException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) IDPECPSessionMapper(com.sun.identity.saml2.plugins.IDPECPSessionMapper) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) Response(com.sun.identity.saml2.protocol.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) ClientFaultException(com.sun.identity.saml2.profile.ClientFaultException) List(java.util.List) CacheObject(com.sun.identity.saml2.profile.CacheObject) FederatedSSOException(com.sun.identity.saml2.profile.FederatedSSOException) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) Map(java.util.Map) IDPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)

Example 2 with IDPAuthnContextMapper

use of com.sun.identity.saml2.plugins.IDPAuthnContextMapper in project OpenAM by OpenRock.

the class IDPSSOUtil method redirectAuthentication.

/**
     * Redirects to authenticate service
     *
     * @param request     the <code>HttpServletRequest</code> object
     * @param response    the <code>HttpServletResponse</code> object
     * @param authnReq    the <code>AuthnRequest</code> object
     * @param reqID       the <code>AuthnRequest ID</code>
     * @param realm       the realm name of the identity provider
     * @param idpEntityID the entity id of the identity provider
     * @param spEntityID  the entity id of the service provider
     */
static void redirectAuthentication(HttpServletRequest request, HttpServletResponse response, AuthnRequest authnReq, String reqID, String realm, String idpEntityID, String spEntityID) throws SAML2Exception, IOException {
    String classMethod = "IDPSSOUtil.redirectAuthentication: ";
    // get the authentication service url 
    StringBuffer newURL = new StringBuffer(IDPSSOUtil.getAuthenticationServiceURL(realm, idpEntityID, request));
    // Pass spEntityID to IdP Auth Module
    if (spEntityID != null) {
        if (newURL.indexOf("?") == -1) {
            newURL.append("?");
        } else {
            newURL.append("&");
        }
        newURL.append(SAML2Constants.SPENTITYID);
        newURL.append("=");
        newURL.append(URLEncDec.encode(spEntityID));
    }
    // find out the authentication method, e.g. module=LDAP, from
    // authn context mapping 
    IDPAuthnContextMapper idpAuthnContextMapper = getIDPAuthnContextMapper(realm, idpEntityID);
    IDPAuthnContextInfo info = idpAuthnContextMapper.getIDPAuthnContextInfo(authnReq, idpEntityID, realm);
    Set authnTypeAndValues = info.getAuthnTypeAndValues();
    if ((authnTypeAndValues != null) && (!authnTypeAndValues.isEmpty())) {
        Iterator iter = authnTypeAndValues.iterator();
        StringBuffer authSB = new StringBuffer((String) iter.next());
        while (iter.hasNext()) {
            authSB.append("&");
            authSB.append((String) iter.next());
        }
        if (newURL.indexOf("?") == -1) {
            newURL.append("?");
        } else {
            newURL.append("&");
        }
        newURL.append(authSB.toString());
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(classMethod + "authString=" + authSB.toString());
        }
    }
    if (newURL.indexOf("?") == -1) {
        newURL.append("?goto=");
    } else {
        newURL.append("&goto=");
    }
    String gotoURL = request.getRequestURL().toString();
    String gotoQuery = request.getQueryString();
    //to the login interface for authentication.
    if (gotoQuery != null) {
        gotoURL += "?" + gotoQuery + "&" + REDIRECTED_TRUE;
    } else {
        gotoURL += "?" + REDIRECTED_TRUE;
    }
    if (reqID != null) {
        gotoURL += "&ReqID=" + reqID;
    }
    if (SAML2Utils.debug.messageEnabled()) {
        SAML2Utils.debug.message(classMethod + "gotoURL=" + gotoURL);
    }
    newURL.append(URLEncDec.encode(gotoURL));
    if (SAML2Utils.debug.messageEnabled()) {
        SAML2Utils.debug.message(classMethod + "New URL for authentication: " + newURL.toString());
    }
    // TODO: here we should check if the new URL is one
    //       the same web container, if yes, forward,
    //       if not, redirect
    response.sendRedirect(newURL.toString());
    return;
}
Also used : IDPAuthnContextInfo(com.sun.identity.saml2.plugins.IDPAuthnContextInfo) IDPAuthnContextMapper(com.sun.identity.saml2.plugins.IDPAuthnContextMapper) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Iterator(java.util.Iterator)

Example 3 with IDPAuthnContextMapper

use of com.sun.identity.saml2.plugins.IDPAuthnContextMapper in project OpenAM by OpenRock.

the class IDPSSOUtil method getIDPAuthnContextMapper.

/**
     * Returns an <code>IDPAuthnContextMapper</code>
     *
     * @param realm       the realm name
     * @param idpEntityID the entity id of the identity provider
     * @return the <code>IDPAuthnContextMapper</code>
     * @throws SAML2Exception if the operation is not successful
     */
public static IDPAuthnContextMapper getIDPAuthnContextMapper(String realm, String idpEntityID) throws SAML2Exception {
    String classMethod = "IDPSSOUtil.getIDPAuthnContextMapper: ";
    String idpAuthnContextMapperName = null;
    IDPAuthnContextMapper idpAuthnContextMapper = null;
    try {
        idpAuthnContextMapperName = getAttributeValueFromIDPSSOConfig(realm, idpEntityID, SAML2Constants.IDP_AUTHNCONTEXT_MAPPER_CLASS);
        if (idpAuthnContextMapperName == null) {
            idpAuthnContextMapperName = SAML2Constants.DEFAULT_IDP_AUTHNCONTEXT_MAPPER_CLASS;
            if (SAML2Utils.debug.messageEnabled()) {
                SAML2Utils.debug.message(classMethod + "use " + SAML2Constants.DEFAULT_IDP_AUTHNCONTEXT_MAPPER_CLASS);
            }
        }
        idpAuthnContextMapper = (IDPAuthnContextMapper) IDPCache.idpAuthnContextMapperCache.get(idpAuthnContextMapperName);
        if (idpAuthnContextMapper == null) {
            idpAuthnContextMapper = (IDPAuthnContextMapper) Class.forName(idpAuthnContextMapperName).newInstance();
            IDPCache.idpAuthnContextMapperCache.put(idpAuthnContextMapperName, idpAuthnContextMapper);
        } else {
            if (SAML2Utils.debug.messageEnabled()) {
                SAML2Utils.debug.message(classMethod + "got the IDPAuthnContextMapper from cache");
            }
        }
    } catch (Exception ex) {
        SAML2Utils.debug.error(classMethod + "Unable to get IDP AuthnContext Mapper.", ex);
        throw new SAML2Exception(ex);
    }
    return idpAuthnContextMapper;
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) IDPAuthnContextMapper(com.sun.identity.saml2.plugins.IDPAuthnContextMapper) SAML2InvalidNameIDPolicyException(com.sun.identity.saml2.common.SAML2InvalidNameIDPolicyException) SessionException(com.sun.identity.plugin.session.SessionException) COTException(com.sun.identity.cot.COTException) 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)

Example 4 with IDPAuthnContextMapper

use of com.sun.identity.saml2.plugins.IDPAuthnContextMapper in project OpenAM by OpenRock.

the class IDPSSOUtil method getAuthnStatement.

/**
     * Returns a <code>SAML AuthnStatement</code> object.
     *
     * @param request The HTTP request.
     * @param session The user's session.
     * @param isNewSessionIndex A returned flag from which the caller knows if the session index in the returned
     *                          <code>AuthnStatement</code> is a new session index.
     * @param authnReq The <code>AuthnRequest</code> object.
     * @param idpEntityID The entity ID of the identity provider.
     * @param realm The realm name.
     * @param matchingAuthnContext The <code>AuthnContext</code> used to find authentication type and scheme.
     * @return The <code>SAML AuthnStatement</code> object.
     * @throws SAML2Exception If the operation is not successful.
     */
private static AuthnStatement getAuthnStatement(HttpServletRequest request, Object session, NewBoolean isNewSessionIndex, AuthnRequest authnReq, String idpEntityID, String realm, AuthnContext matchingAuthnContext) throws SAML2Exception {
    String classMethod = "IDPSSOUtil.getAuthnStatement: ";
    AuthnStatement authnStatement = AssertionFactory.getInstance().createAuthnStatement();
    Date authInstant = null;
    // will be used when we add SubjectLocality to the statement
    try {
        String[] values = sessionProvider.getProperty(session, SessionProvider.AUTH_INSTANT);
        if (values != null && values.length != 0 && values[0] != null && values[0].length() != 0) {
            authInstant = DateUtils.stringToDate(values[0]);
        }
    } catch (Exception e) {
        SAML2Utils.debug.error(classMethod + "exception retrieving info from the session: ", e);
        throw new SAML2Exception(SAML2Utils.bundle.getString("errorGettingAuthnStatement"));
    }
    if (authInstant == null) {
        authInstant = new Date();
    }
    authnStatement.setAuthnInstant(authInstant);
    AuthnContext authnContext = matchingAuthnContext;
    if (authnContext == null) {
        String authLevel = null;
        try {
            String[] values = sessionProvider.getProperty(session, SessionProvider.AUTH_LEVEL);
            if (values != null && values.length != 0 && values[0] != null && values[0].length() != 0) {
                authLevel = values[0];
            }
        } catch (Exception e) {
            SAML2Utils.debug.error(classMethod + "exception retrieving auth level info from the session: ", e);
            throw new SAML2Exception(SAML2Utils.bundle.getString("errorGettingAuthnStatement"));
        }
        IDPAuthnContextMapper idpAuthnContextMapper = getIDPAuthnContextMapper(realm, idpEntityID);
        authnContext = idpAuthnContextMapper.getAuthnContextFromAuthLevel(authLevel, realm, idpEntityID);
    }
    final Response idpResponse = (Response) request.getAttribute(SAML2Constants.SAML_PROXY_IDP_RESPONSE_KEY);
    if (idpResponse != null) {
        // IdP proxy case: we already received an assertion from the remote IdP and now the IdP proxy is generating
        // a new SAML response for the SP.
        Set<String> authenticatingAuthorities = new LinkedHashSet<String>();
        final List<Assertion> assertions = idpResponse.getAssertion();
        for (Assertion assertion : assertions) {
            authenticatingAuthorities.addAll(extractAuthenticatingAuthorities(assertion));
        }
        // According to SAML profile 4.1.4.2 each assertion within the SAML Response MUST have the same issuer, so
        // this should suffice. We should have at least one assertion, since the IdP proxy's SP already accepted it.
        authenticatingAuthorities.add(assertions.iterator().next().getIssuer().getValue());
        authnContext.setAuthenticatingAuthority(new ArrayList<String>(authenticatingAuthorities));
    }
    authnStatement.setAuthnContext(authnContext);
    String sessionIndex = getSessionIndex(session);
    if (sessionIndex == null) {
        // new sessionIndex
        sessionIndex = SAML2Utils.generateIDWithServerID();
        try {
            String[] values = { sessionIndex };
            sessionProvider.setProperty(session, SAML2Constants.IDP_SESSION_INDEX, values);
        } catch (SessionException e) {
            SAML2Utils.debug.error(classMethod + "error setting session index into the session: ", e);
            throw new SAML2Exception(SAML2Utils.bundle.getString("errorGettingAuthnStatement"));
        }
        isNewSessionIndex.setValue(true);
    } else {
        isNewSessionIndex.setValue(false);
    }
    if (SAML2Utils.debug.messageEnabled()) {
        SAML2Utils.debug.message(classMethod + "SessionIndex (in AuthnStatement) =" + sessionIndex);
    }
    if (sessionIndex != null) {
        Set authContextSet = (HashSet) IDPCache.authnContextCache.get(sessionIndex);
        if (authContextSet == null || authContextSet.isEmpty()) {
            authContextSet = new HashSet();
        }
        authContextSet.add(authnContext);
        // cache the AuthContext to use in the case of session upgrade.
        IDPCache.authnContextCache.put(sessionIndex, authContextSet);
        authnStatement.setSessionIndex(sessionIndex);
    }
    return authnStatement;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) IDPAuthnContextMapper(com.sun.identity.saml2.plugins.IDPAuthnContextMapper) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) EncryptedAssertion(com.sun.identity.saml2.assertion.EncryptedAssertion) Assertion(com.sun.identity.saml2.assertion.Assertion) SessionException(com.sun.identity.plugin.session.SessionException) Date(java.util.Date) SAML2InvalidNameIDPolicyException(com.sun.identity.saml2.common.SAML2InvalidNameIDPolicyException) SessionException(com.sun.identity.plugin.session.SessionException) COTException(com.sun.identity.cot.COTException) 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) AuthnContext(com.sun.identity.saml2.assertion.AuthnContext) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) ECPResponse(com.sun.identity.saml2.ecp.ECPResponse) Response(com.sun.identity.saml2.protocol.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) AuthnStatement(com.sun.identity.saml2.assertion.AuthnStatement) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 5 with IDPAuthnContextMapper

use of com.sun.identity.saml2.plugins.IDPAuthnContextMapper in project OpenAM by OpenRock.

the class AuthnQueryUtil method processAuthnQuery.

/**
     * This method processes the <code>AuthnQuery</code> coming
     * from a requester.
     *
     * @param authnQuery the <code>AuthnQuery</code> object
     * @param request the <code>HttpServletRequest</code> object
     * @param response the <code>HttpServletResponse</code> object
     * @param authnAuthorityEntityID entity ID of authentication authority
     * @param realm the realm of hosted entity
     *
     * @return the <code>Response</code> object
     * @exception SAML2Exception if the operation is not successful
     */
public static Response processAuthnQuery(AuthnQuery authnQuery, HttpServletRequest request, HttpServletResponse response, String authnAuthorityEntityID, String realm) throws SAML2Exception {
    try {
        verifyAuthnQuery(authnQuery, authnAuthorityEntityID, realm);
    } catch (SAML2Exception se) {
        SAML2Utils.debug.error("AuthnQueryUtil.processAuthnQuery:", se);
        return SAML2Utils.getErrorResponse(authnQuery, SAML2Constants.REQUESTER, null, se.getMessage(), null);
    }
    Issuer issuer = authnQuery.getIssuer();
    String spEntityID = issuer.getValue();
    AuthnAuthorityDescriptorElement aad = null;
    SAML2MetaManager metaManager = SAML2Utils.getSAML2MetaManager();
    try {
        aad = metaManager.getAuthnAuthorityDescriptor(realm, authnAuthorityEntityID);
    } catch (SAML2MetaException sme) {
        SAML2Utils.debug.error("AuthnQueryUtil.processAuthnQuery:", sme);
        return SAML2Utils.getErrorResponse(authnQuery, SAML2Constants.RESPONDER, null, SAML2Utils.bundle.getString("metaDataError"), null);
    }
    if (aad == null) {
        return SAML2Utils.getErrorResponse(authnQuery, SAML2Constants.REQUESTER, null, SAML2Utils.bundle.getString("authnAuthorityNotFound"), null);
    }
    NameID nameID = getNameID(authnQuery.getSubject(), realm, authnAuthorityEntityID);
    if (nameID == null) {
        return SAML2Utils.getErrorResponse(authnQuery, SAML2Constants.REQUESTER, SAML2Constants.UNKNOWN_PRINCIPAL, null, null);
    }
    IDPAccountMapper idpAcctMapper = SAML2Utils.getIDPAccountMapper(realm, authnAuthorityEntityID);
    String userID = idpAcctMapper.getIdentity(nameID, authnAuthorityEntityID, spEntityID, realm);
    if (userID == null) {
        return SAML2Utils.getErrorResponse(authnQuery, SAML2Constants.REQUESTER, SAML2Constants.UNKNOWN_PRINCIPAL, null, null);
    }
    IDPAuthnContextMapper idpAuthnContextMapper = IDPSSOUtil.getIDPAuthnContextMapper(realm, authnAuthorityEntityID);
    // get assertion for matching authncontext using session
    List returnAssertions = new ArrayList();
    String qSessionIndex = authnQuery.getSessionIndex();
    RequestedAuthnContext requestedAC = authnQuery.getRequestedAuthnContext();
    List assertions = null;
    String cacheKey = userID.toLowerCase();
    AssertionFactory assertionFactory = AssertionFactory.getInstance();
    if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message("AuthnQueryUtil.processAuthnQuery: " + "getting user assertions from DB. user = " + cacheKey);
        }
        List list = null;
        try {
            list = SAML2FailoverUtils.retrieveSAML2TokensWithSecondaryKey(cacheKey);
        } catch (SAML2TokenRepositoryException se) {
            SAML2Utils.debug.error("AuthnQueryUtil.processAuthnQuery: " + "Unable to obtain user assertions from CTS Repository. user = " + cacheKey, se);
        }
        if (list != null && !list.isEmpty()) {
            assertions = new ArrayList();
            for (Iterator iter = list.iterator(); iter.hasNext(); ) {
                String assertionStr = (String) iter.next();
                assertions.add(assertionFactory.createAssertion(assertionStr));
            }
        }
    } else {
        assertions = (List) IDPCache.assertionCache.get(cacheKey);
    }
    if ((assertions != null) && (!assertions.isEmpty())) {
        synchronized (assertions) {
            for (Iterator aIter = assertions.iterator(); aIter.hasNext(); ) {
                Assertion assertion = (Assertion) aIter.next();
                if (!assertion.isTimeValid()) {
                    if (SAML2Utils.debug.messageEnabled()) {
                        SAML2Utils.debug.message("AuthnQueryUtil.processAuthnQuery: " + " assertion " + assertion.getID() + " expired.");
                    }
                    continue;
                }
                List authnStmts = assertion.getAuthnStatements();
                for (Iterator asIter = authnStmts.iterator(); asIter.hasNext(); ) {
                    AuthnStatement authnStmt = (AuthnStatement) asIter.next();
                    AuthnContext authnStmtAC = authnStmt.getAuthnContext();
                    String sessionIndex = authnStmt.getSessionIndex();
                    String authnStmtACClassRef = authnStmtAC.getAuthnContextClassRef();
                    if (SAML2Utils.debug.messageEnabled()) {
                        SAML2Utils.debug.message("AuthnQueryUtil.processAuthnQuery: " + "authnStmtACClassRef is " + authnStmtACClassRef + ", sessionIndex = " + sessionIndex);
                    }
                    if ((qSessionIndex != null) && (qSessionIndex.length() != 0) && (!qSessionIndex.equals(sessionIndex))) {
                        continue;
                    }
                    if (requestedAC != null) {
                        List requestedACClassRefs = requestedAC.getAuthnContextClassRef();
                        String comparison = requestedAC.getComparison();
                        if (idpAuthnContextMapper.isAuthnContextMatching(requestedACClassRefs, authnStmtACClassRef, comparison, realm, authnAuthorityEntityID)) {
                            returnAssertions.add(assertion);
                            break;
                        }
                    } else {
                        returnAssertions.add(assertion);
                        break;
                    }
                }
            }
        }
    // end assertion iterator while.
    }
    ProtocolFactory protocolFactory = ProtocolFactory.getInstance();
    Response samlResp = protocolFactory.createResponse();
    if (!returnAssertions.isEmpty()) {
        samlResp.setAssertion(returnAssertions);
    }
    samlResp.setID(SAML2Utils.generateID());
    samlResp.setInResponseTo(authnQuery.getID());
    samlResp.setVersion(SAML2Constants.VERSION_2_0);
    samlResp.setIssueInstant(new Date());
    Status status = protocolFactory.createStatus();
    StatusCode statusCode = protocolFactory.createStatusCode();
    statusCode.setValue(SAML2Constants.SUCCESS);
    status.setStatusCode(statusCode);
    samlResp.setStatus(status);
    Issuer respIssuer = assertionFactory.createIssuer();
    respIssuer.setValue(authnAuthorityEntityID);
    samlResp.setIssuer(respIssuer);
    signResponse(samlResp, authnAuthorityEntityID, realm, false);
    return samlResp;
}
Also used : Status(com.sun.identity.saml2.protocol.Status) AuthnAuthorityDescriptorElement(com.sun.identity.saml2.jaxb.metadata.AuthnAuthorityDescriptorElement) IDPAccountMapper(com.sun.identity.saml2.plugins.IDPAccountMapper) IDPAuthnContextMapper(com.sun.identity.saml2.plugins.IDPAuthnContextMapper) Issuer(com.sun.identity.saml2.assertion.Issuer) NameID(com.sun.identity.saml2.assertion.NameID) ArrayList(java.util.ArrayList) EncryptedAssertion(com.sun.identity.saml2.assertion.EncryptedAssertion) Assertion(com.sun.identity.saml2.assertion.Assertion) SAML2MetaManager(com.sun.identity.saml2.meta.SAML2MetaManager) StatusCode(com.sun.identity.saml2.protocol.StatusCode) Date(java.util.Date) RequestedAuthnContext(com.sun.identity.saml2.protocol.RequestedAuthnContext) AuthnContext(com.sun.identity.saml2.assertion.AuthnContext) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) ProtocolFactory(com.sun.identity.saml2.protocol.ProtocolFactory) Response(com.sun.identity.saml2.protocol.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) RequestedAuthnContext(com.sun.identity.saml2.protocol.RequestedAuthnContext) AssertionFactory(com.sun.identity.saml2.assertion.AssertionFactory) Iterator(java.util.Iterator) AuthnStatement(com.sun.identity.saml2.assertion.AuthnStatement) ArrayList(java.util.ArrayList) List(java.util.List) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException)

Aggregations

IDPAuthnContextMapper (com.sun.identity.saml2.plugins.IDPAuthnContextMapper)5 SAML2Exception (com.sun.identity.saml2.common.SAML2Exception)4 SAML2MetaException (com.sun.identity.saml2.meta.SAML2MetaException)4 SessionException (com.sun.identity.plugin.session.SessionException)3 Response (com.sun.identity.saml2.protocol.Response)3 IOException (java.io.IOException)3 HttpServletResponse (javax.servlet.http.HttpServletResponse)3 SAML2TokenRepositoryException (org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException)3 COTException (com.sun.identity.cot.COTException)2 Assertion (com.sun.identity.saml2.assertion.Assertion)2 AuthnContext (com.sun.identity.saml2.assertion.AuthnContext)2 AuthnStatement (com.sun.identity.saml2.assertion.AuthnStatement)2 EncryptedAssertion (com.sun.identity.saml2.assertion.EncryptedAssertion)2 SAML2InvalidNameIDPolicyException (com.sun.identity.saml2.common.SAML2InvalidNameIDPolicyException)2 IDPAuthnContextInfo (com.sun.identity.saml2.plugins.IDPAuthnContextInfo)2 Date (java.util.Date)2 HashSet (java.util.HashSet)2 Iterator (java.util.Iterator)2 LinkedHashSet (java.util.LinkedHashSet)2 List (java.util.List)2