Search in sources :

Example 36 with Assertion

use of org.opensaml.saml2.core.Assertion in project spring-security by spring-projects.

the class OpenSaml4AuthenticationProviderTests method authenticateWhenCustomResponseElementsDecrypterThenDecryptsResponse.

@Test
public void authenticateWhenCustomResponseElementsDecrypterThenDecryptsResponse() {
    Response response = response();
    Assertion assertion = assertion();
    TestOpenSamlObjects.signed(assertion, TestSaml2X509Credentials.assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID);
    response.getEncryptedAssertions().add(new EncryptedAssertionBuilder().buildObject());
    TestOpenSamlObjects.signed(response, TestSaml2X509Credentials.assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID);
    Saml2AuthenticationToken token = token(response, verifying(registration()));
    this.provider.setResponseElementsDecrypter((tuple) -> tuple.getResponse().getAssertions().add(assertion));
    Authentication authentication = this.provider.authenticate(token);
    assertThat(authentication.getName()).isEqualTo("test@saml.user");
}
Also used : Response(org.opensaml.saml.saml2.core.Response) Authentication(org.springframework.security.core.Authentication) EncryptedAssertion(org.opensaml.saml.saml2.core.EncryptedAssertion) Assertion(org.opensaml.saml.saml2.core.Assertion) EncryptedAssertionBuilder(org.opensaml.saml.saml2.core.impl.EncryptedAssertionBuilder) Test(org.junit.jupiter.api.Test)

Example 37 with Assertion

use of org.opensaml.saml2.core.Assertion in project spring-security by spring-projects.

the class OpenSaml4AuthenticationProviderTests method authenticateWhenUnknownDataClassThenThrowAuthenticationException.

@Test
public void authenticateWhenUnknownDataClassThenThrowAuthenticationException() {
    Assertion assertion = (Assertion) XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(Assertion.DEFAULT_ELEMENT_NAME).buildObject(Assertion.DEFAULT_ELEMENT_NAME);
    assertThatExceptionOfType(Saml2AuthenticationException.class).isThrownBy(() -> this.provider.authenticate(new Saml2AuthenticationToken(verifying(registration()).build(), serialize(assertion)))).satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA));
}
Also used : EncryptedAssertion(org.opensaml.saml.saml2.core.EncryptedAssertion) Assertion(org.opensaml.saml.saml2.core.Assertion) Test(org.junit.jupiter.api.Test)

Example 38 with Assertion

use of org.opensaml.saml2.core.Assertion in project spring-security by spring-projects.

the class OpenSamlDecryptionUtils method decryptResponseElements.

static void decryptResponseElements(Response response, RelyingPartyRegistration registration) {
    Decrypter decrypter = decrypter(registration);
    for (EncryptedAssertion encryptedAssertion : response.getEncryptedAssertions()) {
        try {
            Assertion assertion = decrypter.decrypt(encryptedAssertion);
            response.getAssertions().add(assertion);
        } catch (Exception ex) {
            throw new Saml2Exception(ex);
        }
    }
}
Also used : EncryptedAssertion(org.opensaml.saml.saml2.core.EncryptedAssertion) EncryptedAssertion(org.opensaml.saml.saml2.core.EncryptedAssertion) Assertion(org.opensaml.saml.saml2.core.Assertion) Decrypter(org.opensaml.saml.saml2.encryption.Decrypter) Saml2Exception(org.springframework.security.saml2.Saml2Exception) Saml2Exception(org.springframework.security.saml2.Saml2Exception)

Example 39 with Assertion

use of org.opensaml.saml2.core.Assertion in project cloudstack by apache.

the class SAML2LoginAPIAuthenticatorCmd method authenticate.

@Override
public String authenticate(final String command, final Map<String, Object[]> params, final HttpSession session, final InetAddress remoteAddress, final String responseType, final StringBuilder auditTrailSb, final HttpServletRequest req, final HttpServletResponse resp) throws ServerApiException {
    try {
        if (!params.containsKey(SAMLPluginConstants.SAML_RESPONSE) && !params.containsKey("SAMLart")) {
            String idpId = null;
            String domainPath = null;
            if (params.containsKey(ApiConstants.IDP_ID)) {
                idpId = ((String[]) params.get(ApiConstants.IDP_ID))[0];
            }
            if (params.containsKey(ApiConstants.DOMAIN)) {
                domainPath = ((String[]) params.get(ApiConstants.DOMAIN))[0];
            }
            if (domainPath != null && !domainPath.isEmpty()) {
                if (!domainPath.startsWith("/")) {
                    domainPath = "/" + domainPath;
                }
                if (!domainPath.endsWith("/")) {
                    domainPath = domainPath + "/";
                }
            }
            SAMLProviderMetadata spMetadata = samlAuthManager.getSPMetadata();
            SAMLProviderMetadata idpMetadata = samlAuthManager.getIdPMetadata(idpId);
            if (idpMetadata == null) {
                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(), "IdP ID (" + idpId + ") is not found in our list of supported IdPs, cannot proceed.", params, responseType));
            }
            if (idpMetadata.getSsoUrl() == null || idpMetadata.getSsoUrl().isEmpty()) {
                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, apiServer.getSerializedApiError(ApiErrorCode.PARAM_ERROR.getHttpCode(), "IdP ID (" + idpId + ") has no Single Sign On URL defined please contact " + idpMetadata.getContactPersonName() + " <" + idpMetadata.getContactPersonEmail() + ">, cannot proceed.", params, responseType));
            }
            String authnId = SAMLUtils.generateSecureRandomId();
            samlAuthManager.saveToken(authnId, domainPath, idpMetadata.getEntityId());
            s_logger.debug("Sending SAMLRequest id=" + authnId);
            String redirectUrl = SAMLUtils.buildAuthnRequestUrl(authnId, spMetadata, idpMetadata, SAML2AuthManager.SAMLSignatureAlgorithm.value());
            resp.sendRedirect(redirectUrl);
            return "";
        }
        if (params.containsKey("SAMLart")) {
            throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, apiServer.getSerializedApiError(ApiErrorCode.UNSUPPORTED_ACTION_ERROR.getHttpCode(), "SAML2 HTTP Artifact Binding is not supported", params, responseType));
        } else {
            final String samlResponse = ((String[]) params.get(SAMLPluginConstants.SAML_RESPONSE))[0];
            Response processedSAMLResponse = this.processSAMLResponse(samlResponse);
            String statusCode = processedSAMLResponse.getStatus().getStatusCode().getValue();
            if (!statusCode.equals(StatusCode.SUCCESS_URI)) {
                throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "Identity Provider send a non-successful authentication status code", params, responseType));
            }
            String username = null;
            Issuer issuer = processedSAMLResponse.getIssuer();
            SAMLProviderMetadata spMetadata = samlAuthManager.getSPMetadata();
            SAMLProviderMetadata idpMetadata = samlAuthManager.getIdPMetadata(issuer.getValue());
            String responseToId = processedSAMLResponse.getInResponseTo();
            s_logger.debug("Received SAMLResponse in response to id=" + responseToId);
            SAMLTokenVO token = samlAuthManager.getToken(responseToId);
            if (token != null) {
                if (!(token.getEntity().equalsIgnoreCase(issuer.getValue()))) {
                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "The SAML response contains Issuer Entity ID that is different from the original SAML request", params, responseType));
                }
            } else {
                throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "Received SAML response for a SSO request that we may not have made or has expired, please try logging in again", params, responseType));
            }
            // Set IdpId for this session
            session.setAttribute(SAMLPluginConstants.SAML_IDPID, issuer.getValue());
            Signature sig = processedSAMLResponse.getSignature();
            if (idpMetadata.getSigningCertificate() != null && sig != null) {
                BasicX509Credential credential = new BasicX509Credential();
                credential.setEntityCertificate(idpMetadata.getSigningCertificate());
                SignatureValidator validator = new SignatureValidator(credential);
                try {
                    validator.validate(sig);
                } catch (ValidationException e) {
                    s_logger.error("SAML Response's signature failed to be validated by IDP signing key:" + e.getMessage());
                    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "SAML Response's signature failed to be validated by IDP signing key", params, responseType));
                }
            }
            if (username == null) {
                username = SAMLUtils.getValueFromAssertions(processedSAMLResponse.getAssertions(), SAML2AuthManager.SAMLUserAttributeName.value());
            }
            for (Assertion assertion : processedSAMLResponse.getAssertions()) {
                if (assertion != null && assertion.getSubject() != null && assertion.getSubject().getNameID() != null) {
                    session.setAttribute(SAMLPluginConstants.SAML_NAMEID, assertion.getSubject().getNameID().getValue());
                    break;
                }
            }
            if (idpMetadata.getEncryptionCertificate() != null && spMetadata != null && spMetadata.getKeyPair() != null && spMetadata.getKeyPair().getPrivate() != null) {
                Credential credential = SecurityHelper.getSimpleCredential(idpMetadata.getEncryptionCertificate().getPublicKey(), spMetadata.getKeyPair().getPrivate());
                StaticKeyInfoCredentialResolver keyInfoResolver = new StaticKeyInfoCredentialResolver(credential);
                EncryptedKeyResolver keyResolver = new InlineEncryptedKeyResolver();
                Decrypter decrypter = new Decrypter(null, keyInfoResolver, keyResolver);
                decrypter.setRootInNewDocument(true);
                List<EncryptedAssertion> encryptedAssertions = processedSAMLResponse.getEncryptedAssertions();
                if (encryptedAssertions != null) {
                    for (EncryptedAssertion encryptedAssertion : encryptedAssertions) {
                        Assertion assertion = null;
                        try {
                            assertion = decrypter.decrypt(encryptedAssertion);
                        } catch (DecryptionException e) {
                            s_logger.warn("SAML EncryptedAssertion error: " + e.toString());
                        }
                        if (assertion == null) {
                            continue;
                        }
                        Signature encSig = assertion.getSignature();
                        if (idpMetadata.getSigningCertificate() != null && encSig != null) {
                            BasicX509Credential sigCredential = new BasicX509Credential();
                            sigCredential.setEntityCertificate(idpMetadata.getSigningCertificate());
                            SignatureValidator validator = new SignatureValidator(sigCredential);
                            try {
                                validator.validate(encSig);
                            } catch (ValidationException e) {
                                s_logger.error("SAML Response's signature failed to be validated by IDP signing key:" + e.getMessage());
                                throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "SAML Response's signature failed to be validated by IDP signing key", params, responseType));
                            }
                        }
                        if (assertion.getSubject() != null && assertion.getSubject().getNameID() != null) {
                            session.setAttribute(SAMLPluginConstants.SAML_NAMEID, assertion.getSubject().getNameID().getValue());
                        }
                        if (username == null) {
                            username = SAMLUtils.getValueFromAttributeStatements(assertion.getAttributeStatements(), SAML2AuthManager.SAMLUserAttributeName.value());
                        }
                    }
                }
            }
            if (username == null) {
                throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "Failed to find admin configured username attribute in the SAML Response. Please ask your administrator to check SAML user attribute name.", params, responseType));
            }
            UserAccount userAccount = null;
            List<UserAccountVO> possibleUserAccounts = userAccountDao.getAllUsersByNameAndEntity(username, issuer.getValue());
            if (possibleUserAccounts != null && possibleUserAccounts.size() > 0) {
                // Users can switch to other allowed accounts later
                for (UserAccountVO possibleUserAccount : possibleUserAccounts) {
                    if (possibleUserAccount.getAccountState().equals(Account.State.enabled.toString())) {
                        userAccount = possibleUserAccount;
                        break;
                    }
                }
            }
            whenFailToAuthenticateThrowExceptionOrRedirectToUrl(params, responseType, resp, issuer, userAccount);
            try {
                if (apiServer.verifyUser(userAccount.getId())) {
                    LoginCmdResponse loginResponse = (LoginCmdResponse) apiServer.loginUser(session, userAccount.getUsername(), userAccount.getUsername() + userAccount.getSource().toString(), userAccount.getDomainId(), null, remoteAddress, params);
                    SAMLUtils.setupSamlUserCookies(loginResponse, resp);
                    resp.sendRedirect(SAML2AuthManager.SAMLCloudStackRedirectionUrl.value());
                    return ApiResponseSerializer.toSerializedString(loginResponse, responseType);
                }
            } catch (CloudAuthenticationException | IOException exception) {
                s_logger.debug("SAML Login failed to log in the user due to: " + exception.getMessage());
            }
        }
    } catch (IOException e) {
        auditTrailSb.append("SP initiated SAML authentication using HTTP redirection failed:");
        auditTrailSb.append(e.getMessage());
    }
    throw new ServerApiException(ApiErrorCode.ACCOUNT_ERROR, apiServer.getSerializedApiError(ApiErrorCode.ACCOUNT_ERROR.getHttpCode(), "Unable to authenticate user while performing SAML based SSO. Please make sure your user/account has been added, enable and authorized by the admin before you can authenticate. Please contact your administrator.", params, responseType));
}
Also used : ValidationException(org.opensaml.xml.validation.ValidationException) Issuer(org.opensaml.saml2.core.Issuer) SAMLTokenVO(org.apache.cloudstack.saml.SAMLTokenVO) CloudAuthenticationException(com.cloud.exception.CloudAuthenticationException) StaticKeyInfoCredentialResolver(org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver) ServerApiException(org.apache.cloudstack.api.ServerApiException) SAMLProviderMetadata(org.apache.cloudstack.saml.SAMLProviderMetadata) BasicX509Credential(org.opensaml.xml.security.x509.BasicX509Credential) Credential(org.opensaml.xml.security.credential.Credential) Assertion(org.opensaml.saml2.core.Assertion) EncryptedAssertion(org.opensaml.saml2.core.EncryptedAssertion) Decrypter(org.opensaml.saml2.encryption.Decrypter) IOException(java.io.IOException) LoginCmdResponse(org.apache.cloudstack.api.response.LoginCmdResponse) Response(org.opensaml.saml2.core.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) UserAccountVO(com.cloud.user.UserAccountVO) BasicX509Credential(org.opensaml.xml.security.x509.BasicX509Credential) EncryptedAssertion(org.opensaml.saml2.core.EncryptedAssertion) Signature(org.opensaml.xml.signature.Signature) SignatureValidator(org.opensaml.xml.signature.SignatureValidator) InlineEncryptedKeyResolver(org.opensaml.xml.encryption.InlineEncryptedKeyResolver) DecryptionException(org.opensaml.xml.encryption.DecryptionException) UserAccount(com.cloud.user.UserAccount) LoginCmdResponse(org.apache.cloudstack.api.response.LoginCmdResponse) InlineEncryptedKeyResolver(org.opensaml.xml.encryption.InlineEncryptedKeyResolver) EncryptedKeyResolver(org.opensaml.xml.encryption.EncryptedKeyResolver)

Example 40 with Assertion

use of org.opensaml.saml2.core.Assertion in project cas by apereo.

the class SamlProfileSaml2ResponseBuilder method buildResponse.

@Override
public Response buildResponse(final Assertion assertion, final SamlProfileBuilderContext context) throws Exception {
    val id = '_' + String.valueOf(RandomUtils.nextLong());
    val samlResponse = newResponse(id, ZonedDateTime.now(ZoneOffset.UTC), context.getSamlRequest().getID(), null);
    samlResponse.setVersion(SAMLVersion.VERSION_20);
    val issuerId = FunctionUtils.doIf(StringUtils.isNotBlank(context.getRegisteredService().getIssuerEntityId()), context.getRegisteredService()::getIssuerEntityId, Unchecked.supplier(() -> {
        val criteriaSet = new CriteriaSet(new EvaluableEntityRoleEntityDescriptorCriterion(IDPSSODescriptor.DEFAULT_ELEMENT_NAME), new SamlIdPSamlRegisteredServiceCriterion(context.getRegisteredService()));
        LOGGER.trace("Resolving entity id from SAML2 IdP metadata to determine issuer for [{}]", context.getRegisteredService().getName());
        val entityDescriptor = Objects.requireNonNull(getConfigurationContext().getSamlIdPMetadataResolver().resolveSingle(criteriaSet));
        return entityDescriptor.getEntityID();
    })).get();
    samlResponse.setIssuer(buildSamlResponseIssuer(issuerId));
    val acs = SamlIdPUtils.determineEndpointForRequest(Pair.of(context.getSamlRequest(), context.getMessageContext()), context.getAdaptor(), context.getBinding());
    val location = StringUtils.isBlank(acs.getResponseLocation()) ? acs.getLocation() : acs.getResponseLocation();
    samlResponse.setDestination(location);
    if (getConfigurationContext().getCasProperties().getAuthn().getSamlIdp().getCore().isAttributeQueryProfileEnabled()) {
        storeAttributeQueryTicketInRegistry(assertion, context);
    }
    val finalAssertion = encryptAssertion(assertion, context);
    if (finalAssertion instanceof EncryptedAssertion) {
        LOGGER.trace("Built assertion is encrypted, so the response will add it to the encrypted assertions collection");
        samlResponse.getEncryptedAssertions().add(EncryptedAssertion.class.cast(finalAssertion));
    } else {
        LOGGER.trace("Built assertion is not encrypted, so the response will add it to the assertions collection");
        samlResponse.getAssertions().add(Assertion.class.cast(finalAssertion));
    }
    val status = newStatus(StatusCode.SUCCESS, null);
    samlResponse.setStatus(status);
    SamlUtils.logSamlObject(this.openSamlConfigBean, samlResponse);
    if (context.getRegisteredService().isSignResponses()) {
        LOGGER.debug("SAML entity id [{}] indicates that SAML responses should be signed", context.getAdaptor().getEntityId());
        val samlResponseSigned = getConfigurationContext().getSamlObjectSigner().encode(samlResponse, context.getRegisteredService(), context.getAdaptor(), context.getHttpResponse(), context.getHttpRequest(), context.getBinding(), context.getSamlRequest(), context.getMessageContext());
        SamlUtils.logSamlObject(openSamlConfigBean, samlResponseSigned);
        return samlResponseSigned;
    }
    return samlResponse;
}
Also used : lombok.val(lombok.val) EvaluableEntityRoleEntityDescriptorCriterion(org.opensaml.saml.metadata.criteria.entity.impl.EvaluableEntityRoleEntityDescriptorCriterion) SamlIdPSamlRegisteredServiceCriterion(org.apereo.cas.support.saml.idp.metadata.locator.SamlIdPSamlRegisteredServiceCriterion) EncryptedAssertion(org.opensaml.saml.saml2.core.EncryptedAssertion) CriteriaSet(net.shibboleth.utilities.java.support.resolver.CriteriaSet) EncryptedAssertion(org.opensaml.saml.saml2.core.EncryptedAssertion) Assertion(org.opensaml.saml.saml2.core.Assertion)

Aggregations

Assertion (org.opensaml.saml.saml2.core.Assertion)175 Test (org.junit.jupiter.api.Test)118 Response (org.opensaml.saml.saml2.core.Response)62 AssertionBuilder.anAssertion (uk.gov.ida.saml.core.test.builders.AssertionBuilder.anAssertion)61 EncryptedAssertion (org.opensaml.saml.saml2.core.EncryptedAssertion)58 AttributeStatement (org.opensaml.saml.saml2.core.AttributeStatement)43 Attribute (org.opensaml.saml.saml2.core.Attribute)25 DateTime (org.joda.time.DateTime)22 Element (org.w3c.dom.Element)22 NameID (org.opensaml.saml.saml2.core.NameID)20 XMLObject (org.opensaml.core.xml.XMLObject)19 PassthroughAssertion (uk.gov.ida.saml.core.domain.PassthroughAssertion)17 ValidatedResponse (uk.gov.ida.saml.security.validators.ValidatedResponse)15 Authentication (org.springframework.security.core.Authentication)14 SubjectConfirmation (org.opensaml.saml.saml2.core.SubjectConfirmation)13 Test (org.junit.Test)12 AuthnStatement (org.opensaml.saml.saml2.core.AuthnStatement)12 Conditions (org.opensaml.saml.saml2.core.Conditions)12 HashMap (java.util.HashMap)11 NameIDBuilder (org.opensaml.saml.saml2.core.impl.NameIDBuilder)11