public TokenValidatorResponse validateAndProcessToken()

in plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java [137:281]


    public TokenValidatorResponse validateAndProcessToken(TokenValidatorRequest request,
            FedizContext config) throws ProcessingException {

        Element token = request.getToken();
        try {
            RequestData requestData = new RequestData();
            WSSConfig wssConfig = WSSConfig.getNewInstance();
            requestData.setWssConfig(wssConfig);
            requestData.setWsDocInfo(new WSDocInfo(token.getOwnerDocument()));
            // not needed as no private key must be read
            // requestData.setCallbackHandler(new
            // PasswordCallbackHandler(password));

            SamlAssertionWrapper assertion = new SamlAssertionWrapper(token);

            boolean doNotEnforceAssertionsSigned = !request.isEnforceTokenSigned();

            boolean trusted = doNotEnforceAssertionsSigned;
            String assertionIssuer = assertion.getIssuerString();

            if (!doNotEnforceAssertionsSigned && !assertion.isSigned()) {
                LOG.warn("Assertion is not signed");
                throw new ProcessingException(TYPE.TOKEN_NO_SIGNATURE);
            }

            if (assertion.isSigned()) {
                // Verify the signature
                Signature sig = assertion.getSignature();
                KeyInfo keyInfo = sig.getKeyInfo();
                final SAMLKeyInfo samlKeyInfo;
                if (keyInfo != null) {
                    samlKeyInfo =
                        org.apache.wss4j.common.saml.SAMLUtil.getCredentialFromKeyInfo(
                            keyInfo.getDOM(), new WSSSAMLKeyInfoProcessor(requestData),
                            requestData.getSigVerCrypto()
                        );
                    assertion.verifySignature(samlKeyInfo);
                } else {
                    samlKeyInfo = validateInCertificatesStore(assertion, config);
                }

                // Parse the subject if it exists
                assertion.parseSubject(
                    new WSSSAMLKeyInfoProcessor(requestData), requestData.getSigVerCrypto(),
                    requestData.getCallbackHandler()
                );

                // Now verify trust on the signature
                Credential trustCredential = new Credential();
                trustCredential.setPublicKey(samlKeyInfo.getPublicKey());
                trustCredential.setCertificates(samlKeyInfo.getCerts());
                trustCredential.setSamlAssertion(assertion);

                SamlAssertionValidator trustValidator = new SamlAssertionValidator();
                trustValidator.setFutureTTL(config.getMaximumClockSkew().intValue());
           
                List<TrustedIssuer> trustedIssuers = config.getTrustedIssuers();
                for (TrustedIssuer ti : trustedIssuers) {
                    Pattern subjectConstraint = ti.getCompiledSubject();
                    List<Pattern> subjectConstraints = new ArrayList<>(1);
                    if (subjectConstraint != null) {
                        subjectConstraints.add(subjectConstraint);
                    }
                
                    if (ti.getCertificateValidationMethod().equals(CertificateValidationMethod.CHAIN_TRUST)) {
                        trustValidator.setSubjectConstraints(subjectConstraints);
                        trustValidator.setSignatureTrustType(TrustType.CHAIN_TRUST_CONSTRAINTS);
                    } else if (ti.getCertificateValidationMethod().equals(CertificateValidationMethod.PEER_TRUST)) {
                        trustValidator.setSignatureTrustType(TrustType.PEER_TRUST);
                    } else {
                        throw new IllegalStateException("Unsupported certificate validation method: "
                                                        + ti.getCertificateValidationMethod());
                    }
                    try {
                        for (TrustManager tm: config.getCertificateStores()) {
                            try {
                                requestData.setSigVerCrypto(tm.getCrypto());
                                trustValidator.validate(trustCredential, requestData);
                                trusted = true;
                                break;
                            } catch (Exception ex) {
                                LOG.debug("Issuer '{}' not validated in keystore '{}'",
                                          ti.getName(), tm.getName());
                            }
                        }
                        if (trusted) {
                            break;
                        }
                
                    } catch (Exception ex) {
                        if (LOG.isInfoEnabled()) {
                            LOG.info("Issuer '" + assertionIssuer + "' doesn't match trusted issuer '" + ti.getName()
                                     + "': " + ex.getMessage());
                        }
                    }
                }
            }

            if (!trusted) {
                // Condition already checked in SamlAssertionValidator
                // Minor performance impact on untrusted and expired tokens
                if (!isConditionValid(assertion, config.getMaximumClockSkew().intValue())) {
                    LOG.warn("Security token expired");
                    throw new ProcessingException(TYPE.TOKEN_EXPIRED);
                } else {
                    LOG.warn("Issuer '" + assertionIssuer + "' not trusted");
                    throw new ProcessingException(TYPE.ISSUER_NOT_TRUSTED);
                }
            }

            // Now check for HolderOfKey requirements
            if (!SAMLUtil.checkHolderOfKey(assertion, request.getCerts())) {
                LOG.warn("Assertion fails holder-of-key requirements");
                throw new ProcessingException(TYPE.ISSUER_NOT_TRUSTED);
            }

            String audience = null;
            List<Claim> claims;
            if (assertion.getSamlVersion().equals(SAMLVersion.VERSION_20)) {
                claims = parseClaimsInAssertion(assertion.getSaml2());
                audience = getAudienceRestriction(assertion.getSaml2());
            } else if (assertion.getSamlVersion().equals(SAMLVersion.VERSION_11)) {
                claims = parseClaimsInAssertion(assertion.getSaml1());
                audience = getAudienceRestriction(assertion.getSaml1());
            } else {
                claims = Collections.emptyList();
            }

            claims = parseRoleClaim(config, claims);
            
            SAMLTokenPrincipal p = new SAMLTokenPrincipalImpl(assertion);

            TokenValidatorResponse response = new TokenValidatorResponse(
                    assertion.getId(), p.getName(), assertionIssuer,
                    new ClaimCollection(claims), audience);
            response.setExpires(getExpires(assertion));
            response.setCreated(getCreated(assertion));

            return response;

        } catch (WSSecurityException ex) {
            LOG.error("Security token validation failed", ex);
            throw new ProcessingException(TYPE.TOKEN_INVALID);
        }
    }