Hide Forgot
Consider a setup with two different IDP that are allowed to create valid SAML-ticket to our service provider (PicketLink on JBoss EAP 6.4.4, same in 6.4.9). The IDP's of course have different certificates for signing these SAML-tickets, so we would like so verify them by using ValidatingAlias in picketlink.xml. Since ValidationAlias uses the hostname of the IDP to look up the correct certificate in the keystore to validate the SAML-response, it should be easy to configure. Just add two ValidationAlias with the hostname for each IDP and let them point to the right alias fort its certificate. Unfortunately this doesn't work. Picketlink only recognize the IDP that is defined under IdentityURL. So the problem is that SAML2AuthenticationHandler always uses this value when looking up the certificate, but it should instead use the Issuer-value in the SAML-response to look up the certificate. A code inspection done shows: This first snippet is from org.picketlink.identity.federation.web.handlers.saml2.SAML2SignatureValidationHandler.validateSender() and it gets the public key to verify the signature from the request instance: ... PublicKey publicKey = (PublicKey) request.getOptions().get(GeneralConstants.SENDER_PUBLIC_KEY); try { boolean isValid; HTTPContext httpContext = (HTTPContext) request.getContext(); logger.trace("HTTP method for validating response: " + httpContext.getRequest().getMethod()); if (isPostBinding(httpContext)) { isValid = verifyPostBindingSignature(signedDocument, publicKey); } else { isValid = verifyRedirectBindingSignature(httpContext, publicKey); } ... That public key is set in the request here: org.picketlink.identity.federation.web.process.ServiceProviderBaseProcessor.setRequestOptions() ... if (keyManager != null) { PublicKey validatingKey = getIDPPublicKey(); requestOptions.put(GeneralConstants.SENDER_PUBLIC_KEY, validatingKey); requestOptions.put(GeneralConstants.DECRYPTING_KEY, keyManager.getSigningKey()); } ... And the actual problem is how the key is retrieved from the keystore in the method getIDPPublicKey(). That method gets a URL from the "IdentityURL" in the picketlink-configuration which is a static URL. What it should do is to get the URL from the "Issuer"-tag in SAML-response. Picketlink uses that URL to get an alias for the certificate in the keystore provided in the ValidatingAlias-configuration. picketlink.xml: ... <ValidatingAlias Key="${picketlink.idp.address}" Value="adfs-sign" /> <ValidatingAlias Key="${picketlink.idp-ext.address}" Value="adfs-sign-ext" /> ... org.picketlink.identity.federation.web.process.ServiceProviderBaseProcessor.getIDPPublicKey() ... if (isNullOrEmpty(idpValidatingAlias)) { idpValidatingAlias = safeURL(getSpConfiguration().getIdentityURL()).getHost(); } return keyManager.getValidatingKey(idpValidatingAlias); And the certificate check will fail.