diff --git a/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java b/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java index 89d6bf3cf7b..69025c23d8e 100755 --- a/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java +++ b/services/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java @@ -161,13 +161,15 @@ public class SamlProtocol implements LoginProtocol { @Override public Response sendError(ClientSessionModel clientSession, Error error) { try { - if ("true".equals(clientSession.getClient().getAttribute(SAML_IDP_INITIATED_LOGIN))) { + ClientModel client = clientSession.getClient(); + + if ("true".equals(client.getAttribute(SAML_IDP_INITIATED_LOGIN))) { if (error == Error.CANCELLED_BY_USER) { UriBuilder builder = RealmsResource.protocolUrl(uriInfo).path(SamlService.class, "idpInitiatedSSO"); Map params = new HashMap<>(); params.put("realm", realm.getName()); params.put("protocol", LOGIN_PROTOCOL); - params.put("client", clientSession.getClient().getAttribute(SAML_IDP_INITIATED_SSO_URL_NAME)); + params.put("client", client.getAttribute(SAML_IDP_INITIATED_SSO_URL_NAME)); URI redirect = builder.buildFromMap(params); return Response.status(302).location(redirect).build(); } else { @@ -177,6 +179,27 @@ public class SamlProtocol implements LoginProtocol { SAML2ErrorResponseBuilder builder = new SAML2ErrorResponseBuilder().destination(clientSession.getRedirectUri()).issuer(getResponseIssuer(realm)).status(translateErrorToSAMLStatus(error).get()); try { JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder().relayState(clientSession.getNote(GeneralConstants.RELAY_STATE)); + SamlClient samlClient = new SamlClient(client); + KeyManager keyManager = session.keys(); + if (samlClient.requiresRealmSignature()) { + KeyManager.ActiveRsaKey keys = keyManager.getActiveRsaKey(realm); + String keyName = samlClient.getXmlSigKeyInfoKeyNameTransformer().getKeyName(keys.getKid(), keys.getCertificate()); + String canonicalization = samlClient.getCanonicalizationMethod(); + if (canonicalization != null) { + binding.canonicalizationMethod(canonicalization); + } + binding.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keyName, keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument(); + } + if (samlClient.requiresEncryption()) { + PublicKey publicKey; + try { + publicKey = SamlProtocolUtils.getEncryptionValidationKey(client); + } catch (Exception e) { + logger.error("failed", e); + return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE); + } + binding.encrypt(publicKey); + } Document document = builder.buildDocument(); return buildErrorResponse(clientSession, binding, document); } catch (Exception e) {