requestData.setWssConfig(wssConfig);
// not needed as no private key must be read
// requestData.setCallbackHandler(new
// PasswordCallbackHandler(password));
AssertionWrapper assertion = new AssertionWrapper(token);
if (!assertion.isSigned()) {
LOG.warn("Assertion is not signed");
throw new ProcessingException(TYPE.TOKEN_NO_SIGNATURE);
}
// Verify the signature
assertion.verifySignature(requestData,
new WSDocInfo(token.getOwnerDocument()));
// Now verify trust on the signature
Credential trustCredential = new Credential();
SAMLKeyInfo samlKeyInfo = assertion.getSignatureKeyInfo();
trustCredential.setPublicKey(samlKeyInfo.getPublicKey());
trustCredential.setCertificates(samlKeyInfo.getCerts());
trustCredential.setAssertion(assertion);
SamlAssertionValidator trustValidator = new SamlAssertionValidator();
trustValidator.setFutureTTL(config.getMaximumClockSkew().intValue());
boolean trusted = false;
String assertionIssuer = assertion.getIssuerString();
List<TrustedIssuer> trustedIssuers = config.getTrustedIssuers();
for (TrustedIssuer ti : trustedIssuers) {
List<String> subjectConstraints = Collections.singletonList(ti.getSubject());
if (ti.getCertificateValidationMethod().equals(CertificateValidationMethod.CHAIN_TRUST)) {
trustValidator.setSubjectConstraints(subjectConstraints);
trustValidator.setSignatureTrustType(TRUST_TYPE.CHAIN_TRUST_CONSTRAINTS);
} else if (ti.getCertificateValidationMethod().equals(CertificateValidationMethod.PEER_TRUST)) {
trustValidator.setSignatureTrustType(TRUST_TYPE.PEER_TRUST);
} else {
throw new IllegalStateException("Unsupported certificate validation method: "
+ ti.getCertificateValidationMethod());
}
try {
for (TrustManager tm: config.getCertificateStores()) {
try {
requestData.setSigCrypto(tm.getCrypto());
trustValidator.validate(trustCredential, requestData);
trusted = true;
break;
} catch (Exception ex) {
if (LOG.isDebugEnabled()) {
LOG.debug("Issuer '" + ti.getName() + "' not validated in keystore '"
+ 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);
}
}
String audience = null;
List<Claim> claims = null;
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());
}
List<String> roles = null;
FederationProtocol fp = (FederationProtocol)config.getProtocol();
if (fp.getRoleURI() != null) {
URI roleURI = URI.create(fp.getRoleURI());
String delim = fp.getRoleDelimiter();
for (Claim c : claims) {
if (roleURI.equals(c.getClaimType())) {
Object oValue = c.getValue();
if (oValue instanceof String) {
if (delim == null) {
roles = Collections.singletonList((String)oValue);
} else {
roles = parseRoles((String)oValue, delim);
}
} else if (oValue instanceof List<?>) {
List<String> values = (List<String>)oValue;
roles = Collections.unmodifiableList(values);
} else {
LOG.error("Unsupported value type of Claim value");
throw new IllegalStateException("Unsupported value type of Claim value");
}
claims.remove(c);
break;
}
}
}
SAMLTokenPrincipal p = new SAMLTokenPrincipal(assertion);
TokenValidatorResponse response = new TokenValidatorResponse(
assertion.getId(), p.getName(), assertionIssuer, roles,
new ClaimCollection(claims), audience);
response.setExpires(getExpires(assertion));
return response;