From 1e9c09d23a0b4ed28f105fc3fb5ba4c164e6004f Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Wed, 23 Sep 2015 17:54:16 -0400 Subject: [PATCH] more complete --- .../adapters/InMemorySessionIdMapper.java | 8 +- ...ssionIdMaper.java => SessionIdMapper.java} | 2 +- .../adapters/saml/DefaultSamlDeployment.java | 45 +++---- .../keycloak/adapters/saml/InitiateLogin.java | 19 +-- .../adapters/saml/SamlAuthenticator.java | 52 +++++--- .../adapters/saml/SamlDeployment.java | 5 +- .../org/keycloak/adapters/saml/SamlUtil.java | 10 +- .../keycloak/adapters/saml/config/IDP.java | 18 --- .../org/keycloak/adapters/saml/config/SP.java | 18 +++ .../config/parsers/ConfigXmlConstants.java | 3 +- .../config/parsers/DeploymentBuilder.java | 124 ++++++++++-------- .../saml/config/parsers/IDPXmlParser.java | 2 - .../saml/config/parsers/SPXmlParser.java | 2 + .../test/adapters/saml/XmlParserTest.java | 2 - .../core/src/test/resources/keycloak-saml.xml | 10 +- .../saml/undertow/ServletSamlAuthMech.java | 5 +- .../undertow/ServletSamlSessionStore.java | 44 ++++++- .../keycloak/protocol/saml/SamlProtocol.java | 1 + .../keycloaksaml/SamlBindingTest.java | 19 ++- .../WEB-INF/keycloak-saml.xml | 44 +++++++ .../signed-front-get/WEB-INF/keystore.jks | Bin 0 -> 1701 bytes .../signed-get/WEB-INF/keycloak-saml.xml | 44 +++++++ .../signed-get/WEB-INF/keystore.jks | Bin 0 -> 1701 bytes .../WEB-INF/keycloak-saml.xml | 44 +++++++ .../signed-post-email/WEB-INF/keystore.jks | Bin 0 -> 1705 bytes .../WEB-INF/keycloak-saml.xml | 45 +++++++ .../WEB-INF/keystore.jks | Bin 0 -> 1705 bytes .../WEB-INF/keycloak-saml.xml | 45 +++++++ .../WEB-INF/keystore.jks | Bin 0 -> 1705 bytes .../simple-post/WEB-INF/keycloak-saml.xml | 24 ++++ .../resources/keycloak-saml/testsaml.json | 2 +- 31 files changed, 481 insertions(+), 156 deletions(-) rename integration/adapter-spi/src/main/java/org/keycloak/adapters/{SessionIdMaper.java => SessionIdMapper.java} (90%) create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keycloak-saml.xml create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keystore.jks create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/signed-get/WEB-INF/keycloak-saml.xml create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/signed-get/WEB-INF/keystore.jks create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keycloak-saml.xml create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keystore.jks create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keycloak-saml.xml create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keystore.jks create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keycloak-saml.xml create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keystore.jks create mode 100755 testsuite/integration/src/test/resources/keycloak-saml/simple-post/WEB-INF/keycloak-saml.xml diff --git a/integration/adapter-spi/src/main/java/org/keycloak/adapters/InMemorySessionIdMapper.java b/integration/adapter-spi/src/main/java/org/keycloak/adapters/InMemorySessionIdMapper.java index 8225ae26f6..4470c150f9 100755 --- a/integration/adapter-spi/src/main/java/org/keycloak/adapters/InMemorySessionIdMapper.java +++ b/integration/adapter-spi/src/main/java/org/keycloak/adapters/InMemorySessionIdMapper.java @@ -11,7 +11,7 @@ import java.util.concurrent.ConcurrentHashMap; * @author Bill Burke * @version $Revision: 1 $ */ -public class InMemorySessionIdMapper implements SessionIdMaper { +public class InMemorySessionIdMapper implements SessionIdMapper { ConcurrentHashMap ssoToSession = new ConcurrentHashMap<>(); ConcurrentHashMap sessionToSso = new ConcurrentHashMap<>(); ConcurrentHashMap> principalToSession = new ConcurrentHashMap<>(); @@ -33,8 +33,10 @@ public class InMemorySessionIdMapper implements SessionIdMaper { @Override public void map(String sso, String principal, String session) { - ssoToSession.put(sso, session); - sessionToSso.put(session, sso); + if (sso != null) { + ssoToSession.put(sso, session); + sessionToSso.put(session, sso); + } Set userSessions = principalToSession.get(principal); if (userSessions == null) { final Set tmp = Collections.synchronizedSet(new HashSet()); diff --git a/integration/adapter-spi/src/main/java/org/keycloak/adapters/SessionIdMaper.java b/integration/adapter-spi/src/main/java/org/keycloak/adapters/SessionIdMapper.java similarity index 90% rename from integration/adapter-spi/src/main/java/org/keycloak/adapters/SessionIdMaper.java rename to integration/adapter-spi/src/main/java/org/keycloak/adapters/SessionIdMapper.java index 8e86b1ecd2..646f71b429 100755 --- a/integration/adapter-spi/src/main/java/org/keycloak/adapters/SessionIdMaper.java +++ b/integration/adapter-spi/src/main/java/org/keycloak/adapters/SessionIdMapper.java @@ -6,7 +6,7 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public interface SessionIdMaper { +public interface SessionIdMapper { Set getUserSessions(String principal); String getSessionFromSSO(String sso); diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java index 65612b3822..28a4eadc92 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/DefaultSamlDeployment.java @@ -3,6 +3,7 @@ package org.keycloak.adapters.saml; import org.keycloak.adapters.saml.SamlDeployment; import org.keycloak.adapters.saml.config.IDP; import org.keycloak.enums.SslRequired; +import org.keycloak.saml.SignatureAlgorithm; import java.security.KeyPair; import java.security.PrivateKey; @@ -18,7 +19,6 @@ public class DefaultSamlDeployment implements SamlDeployment { public static class DefaultSingleSignOnService implements IDP.SingleSignOnService { private boolean signRequest; private boolean validateResponseSignature; - private String signatureCanonicalizationMethod; private Binding requestBinding; private Binding responseBinding; private String requestBindingUrl; @@ -33,12 +33,7 @@ public class DefaultSamlDeployment implements SamlDeployment { return validateResponseSignature; } - @Override - public String getSignatureCanonicalizationMethod() { - return signatureCanonicalizationMethod; - } - - @Override + @Override public Binding getRequestBinding() { return requestBinding; } @@ -61,10 +56,6 @@ public class DefaultSamlDeployment implements SamlDeployment { this.validateResponseSignature = validateResponseSignature; } - public void setSignatureCanonicalizationMethod(String signatureCanonicalizationMethod) { - this.signatureCanonicalizationMethod = signatureCanonicalizationMethod; - } - public void setRequestBinding(Binding requestBinding) { this.requestBinding = requestBinding; } @@ -83,7 +74,6 @@ public class DefaultSamlDeployment implements SamlDeployment { private boolean validateResponseSignature; private boolean signRequest; private boolean signResponse; - private String signatureCanonicalizationMethod; private Binding requestBinding; private Binding responseBinding; private String requestBindingUrl; @@ -109,12 +99,7 @@ public class DefaultSamlDeployment implements SamlDeployment { return signResponse; } - @Override - public String getSignatureCanonicalizationMethod() { - return signatureCanonicalizationMethod; - } - - @Override + @Override public Binding getRequestBinding() { return requestBinding; } @@ -150,10 +135,6 @@ public class DefaultSamlDeployment implements SamlDeployment { this.signResponse = signResponse; } - public void setSignatureCanonicalizationMethod(String signatureCanonicalizationMethod) { - this.signatureCanonicalizationMethod = signatureCanonicalizationMethod; - } - public void setRequestBinding(Binding requestBinding) { this.requestBinding = requestBinding; } @@ -233,6 +214,8 @@ public class DefaultSamlDeployment implements SamlDeployment { private PrincipalNamePolicy principalNamePolicy = PrincipalNamePolicy.FROM_NAME_ID; private String principalAttributeName; private String logoutPage; + private SignatureAlgorithm signatureAlgorithm; + private String signatureCanonicalizationMethod; @Override @@ -360,4 +343,22 @@ public class DefaultSamlDeployment implements SamlDeployment { public void setLogoutPage(String logoutPage) { this.logoutPage = logoutPage; } + + @Override + public String getSignatureCanonicalizationMethod() { + return signatureCanonicalizationMethod; + } + + public void setSignatureCanonicalizationMethod(String signatureCanonicalizationMethod) { + this.signatureCanonicalizationMethod = signatureCanonicalizationMethod; + } + + @Override + public SignatureAlgorithm getSignatureAlgorithm() { + return signatureAlgorithm; + } + + public void setSignatureAlgorithm(SignatureAlgorithm signatureAlgorithm) { + this.signatureAlgorithm = signatureAlgorithm; + } } diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java index 690a99cc13..1cef2b160a 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/InitiateLogin.java @@ -43,18 +43,21 @@ public class InitiateLogin implements AuthChallenge { nameIDPolicyFormat = JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get(); } - String protocolBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get(); - if (deployment.getIDP().getSingleSignOnService().getResponseBinding() == SamlDeployment.Binding.POST) { - protocolBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get(); - } SAML2AuthnRequestBuilder authnRequestBuilder = new SAML2AuthnRequestBuilder() .destination(destinationUrl) .issuer(issuerURL) .forceAuthn(deployment.isForceAuthentication()) - .protocolBinding(protocolBinding) .nameIdPolicy(SAML2NameIDPolicyBuilder.format(nameIDPolicyFormat)); + if (deployment.getIDP().getSingleSignOnService().getResponseBinding() != null) { + String protocolBinding = JBossSAMLURIConstants.SAML_HTTP_REDIRECT_BINDING.get(); + if (deployment.getIDP().getSingleSignOnService().getResponseBinding() == SamlDeployment.Binding.POST) { + protocolBinding = JBossSAMLURIConstants.SAML_HTTP_POST_BINDING.get(); + } + authnRequestBuilder.protocolBinding(protocolBinding); + + } if (deployment.getAssertionConsumerServiceUrl() != null) { authnRequestBuilder.assertionConsumerUrl(deployment.getAssertionConsumerServiceUrl()); } @@ -67,8 +70,8 @@ public class InitiateLogin implements AuthChallenge { if (keypair == null) { throw new RuntimeException("Signing keys not configured"); } - if (deployment.getIDP().getSingleSignOnService().getSignatureCanonicalizationMethod() != null) { - binding.canonicalizationMethod(deployment.getIDP().getSingleSignOnService().getSignatureCanonicalizationMethod()); + if (deployment.getSignatureCanonicalizationMethod() != null) { + binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod()); } binding.signWith(keypair); @@ -78,7 +81,7 @@ public class InitiateLogin implements AuthChallenge { Document document = authnRequestBuilder.toDocument(); SamlDeployment.Binding samlBinding = deployment.getIDP().getSingleSignOnService().getRequestBinding(); - SamlUtil.sendSaml(httpFacade, actionUrl, binding, document, samlBinding); + SamlUtil.sendSaml(true, httpFacade, actionUrl, binding, document, samlBinding); } catch (Exception e) { throw new RuntimeException("Could not create authentication request.", e); } diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java index ca2da00ea5..99c8c13e15 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlAuthenticator.java @@ -25,11 +25,11 @@ import org.keycloak.saml.common.constants.GeneralConstants; import org.keycloak.saml.common.exceptions.ConfigurationException; import org.keycloak.saml.common.exceptions.ParsingException; import org.keycloak.saml.common.exceptions.ProcessingException; +import org.keycloak.saml.common.util.Base64; import org.keycloak.saml.processing.api.saml.v2.sig.SAML2Signature; import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder; import org.keycloak.saml.processing.core.saml.v2.util.AssertionUtil; import org.keycloak.saml.processing.web.util.PostBindingUtil; -import org.keycloak.saml.processing.web.util.RedirectBindingUtil; import org.keycloak.util.KeycloakUriBuilder; import org.keycloak.util.MultivaluedHashMap; import org.w3c.dom.Document; @@ -103,7 +103,7 @@ public abstract class SamlAuthenticator { binding.relayState("logout"); try { - SamlUtil.sendSaml(facade, deployment.getIDP().getSingleLogoutService().getRequestBindingUrl(), binding, logoutBuilder.buildDocument(), deployment.getIDP().getSingleLogoutService().getRequestBinding()); + SamlUtil.sendSaml(true, facade, deployment.getIDP().getSingleLogoutService().getRequestBindingUrl(), binding, logoutBuilder.buildDocument(), deployment.getIDP().getSingleLogoutService().getRequestBinding()); } catch (ProcessingException e) { throw new RuntimeException(e); } catch (ConfigurationException e) { @@ -119,15 +119,22 @@ public abstract class SamlAuthenticator { protected AuthOutcome handleSamlRequest(String samlRequest, String relayState) { SAMLDocumentHolder holder = null; boolean postBinding = false; + String requestUri = facade.getRequest().getURI(); if (facade.getRequest().getMethod().equalsIgnoreCase("GET")) { + // strip out query params + int index = requestUri.indexOf('?'); + if (index > -1) { + requestUri = requestUri.substring(0, index); + } holder = SAMLRequestParser.parseRequestRedirectBinding(samlRequest); } else { postBinding = true; holder = SAMLRequestParser.parseRequestPostBinding(samlRequest); } RequestAbstractType requestAbstractType = (RequestAbstractType) holder.getSamlObject(); - if (!facade.getRequest().getURI().toString().equals(requestAbstractType.getDestination())) { - throw new RuntimeException("destination not equal to request"); + if (!requestUri.equals(requestAbstractType.getDestination().toString())) { + log.error("expected destination '" + requestUri + "' got '" + requestAbstractType.getDestination() + "'"); + throw new RuntimeException("destination not equal to request."); } if (requestAbstractType instanceof LogoutRequestType) { @@ -156,14 +163,15 @@ public abstract class SamlAuthenticator { builder.issuer(issuerURL); BaseSAML2BindingBuilder binding = new BaseSAML2BindingBuilder().relayState(relayState); if (deployment.getIDP().getSingleLogoutService().signResponse()) { - binding.signWith(deployment.getSigningKeyPair()) + binding.signatureAlgorithm(deployment.getSignatureAlgorithm()) + .signWith(deployment.getSigningKeyPair()) .signDocument(); - binding.canonicalizationMethod(deployment.getIDP().getSingleLogoutService().getSignatureCanonicalizationMethod()); + if (deployment.getSignatureCanonicalizationMethod() != null) binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod()); } try { - SamlUtil.sendSaml(facade, deployment.getIDP().getSingleLogoutService().getResponseBindingUrl(), binding, builder.buildDocument(), + SamlUtil.sendSaml(false, facade, deployment.getIDP().getSingleLogoutService().getResponseBindingUrl(), binding, builder.buildDocument(), deployment.getIDP().getSingleLogoutService().getResponseBinding()); } catch (ConfigurationException e) { throw new RuntimeException(e); @@ -180,7 +188,12 @@ public abstract class SamlAuthenticator { protected AuthOutcome handleSamlResponse(String samlResponse, String relayState) { SAMLDocumentHolder holder = null; boolean postBinding = false; + String requestUri = facade.getRequest().getURI(); if (facade.getRequest().getMethod().equalsIgnoreCase("GET")) { + int index = requestUri.indexOf('?'); + if (index > -1) { + requestUri = requestUri.substring(0, index); + } holder = extractRedirectBindingResponse(samlResponse); } else { postBinding = true; @@ -188,18 +201,18 @@ public abstract class SamlAuthenticator { } StatusResponseType statusResponse = (StatusResponseType)holder.getSamlObject(); // validate destination - if (!facade.getRequest().getURI().toString().equals(statusResponse.getDestination())) { + if (!requestUri.equals(statusResponse.getDestination())) { throw new RuntimeException("destination not equal to request"); } if (statusResponse instanceof ResponseType) { if (deployment.getIDP().getSingleSignOnService().validateResponseSignature()) { - validateSamlSignature(holder, postBinding, GeneralConstants.SAML_REQUEST_KEY); + validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY); } return handleLoginResponse((ResponseType)statusResponse); } else { if (deployment.getIDP().getSingleLogoutService().validateResponseSignature()) { - validateSamlSignature(holder, postBinding, GeneralConstants.SAML_REQUEST_KEY); + validateSamlSignature(holder, postBinding, GeneralConstants.SAML_RESPONSE_KEY); } // todo need to check that it is actually a LogoutResponse return handleLogoutResponse(holder, statusResponse, relayState); @@ -320,10 +333,16 @@ public abstract class SamlAuthenticator { sessionStore.saveAccount(account); completeAuthentication(account); + // redirect to original request, it will be restored - facade.getResponse().setHeader("Location", sessionStore.getRedirectUri()); - facade.getResponse().setStatus(302); - facade.getResponse().end(); + String redirectUri = sessionStore.getRedirectUri(); + if (redirectUri != null) { + facade.getResponse().setHeader("Location", redirectUri); + facade.getResponse().setStatus(302); + facade.getResponse().end(); + } else { + log.debug("IDP initiated invocation"); + } return AuthOutcome.AUTHENTICATED; @@ -400,7 +419,9 @@ public abstract class SamlAuthenticator { String signature = facade.getRequest().getQueryParamValue(GeneralConstants.SAML_SIGNATURE_REQUEST_KEY); String decodedAlgorithm = facade.getRequest().getQueryParamValue(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY); - if (request == null) throw new VerificationException("SAM was null"); + if (request == null) { + throw new VerificationException("SAML Request was null"); + } if (algorithm == null) throw new VerificationException("SigAlg was null"); if (signature == null) throw new VerificationException("Signature was null"); @@ -417,7 +438,8 @@ public abstract class SamlAuthenticator { String rawQuery = builder.build().getRawQuery(); try { - byte[] decodedSignature = RedirectBindingUtil.urlBase64Decode(signature); + //byte[] decodedSignature = RedirectBindingUtil.urlBase64Decode(signature); + byte[] decodedSignature = Base64.decode(signature); SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.getFromXmlMethod(decodedAlgorithm); Signature validator = signatureAlgorithm.createSignature(); // todo plugin signature alg diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java index 9363624df8..4540b253bd 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlDeployment.java @@ -1,6 +1,7 @@ package org.keycloak.adapters.saml; import org.keycloak.enums.SslRequired; +import org.keycloak.saml.SignatureAlgorithm; import java.security.KeyPair; import java.security.PrivateKey; @@ -32,7 +33,6 @@ public interface SamlDeployment { public interface SingleSignOnService { boolean signRequest(); boolean validateResponseSignature(); - String getSignatureCanonicalizationMethod(); Binding getRequestBinding(); Binding getResponseBinding(); String getRequestBindingUrl(); @@ -42,7 +42,6 @@ public interface SamlDeployment { boolean validateResponseSignature(); boolean signRequest(); boolean signResponse(); - String getSignatureCanonicalizationMethod(); Binding getRequestBinding(); Binding getResponseBinding(); String getRequestBindingUrl(); @@ -59,6 +58,8 @@ public interface SamlDeployment { boolean isForceAuthentication(); PrivateKey getDecryptionKey(); KeyPair getSigningKeyPair(); + String getSignatureCanonicalizationMethod(); + SignatureAlgorithm getSignatureAlgorithm(); String getAssertionConsumerServiceUrl(); String getLogoutPage(); diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlUtil.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlUtil.java index b0981db790..e0ea5ecb97 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlUtil.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/SamlUtil.java @@ -13,9 +13,11 @@ import java.io.IOException; * @version $Revision: 1 $ */ public class SamlUtil { - public static void sendSaml(HttpFacade httpFacade, String actionUrl, BaseSAML2BindingBuilder binding, Document document, SamlDeployment.Binding samlBinding) throws ProcessingException, ConfigurationException, IOException { + public static void sendSaml(boolean asRequest, HttpFacade httpFacade, String actionUrl, + BaseSAML2BindingBuilder binding, Document document, + SamlDeployment.Binding samlBinding) throws ProcessingException, ConfigurationException, IOException { if (samlBinding == SamlDeployment.Binding.POST) { - String html = binding.postBinding(document).getHtmlRequest(actionUrl); + String html = asRequest ? binding.postBinding(document).getHtmlRequest(actionUrl) : binding.postBinding(document).getHtmlResponse(actionUrl) ; httpFacade.getResponse().setStatus(200); httpFacade.getResponse().setHeader("Content-Type", "text/html"); httpFacade.getResponse().setHeader("Pragma", "no-cache"); @@ -23,9 +25,11 @@ public class SamlUtil { httpFacade.getResponse().getOutputStream().write(html.getBytes()); httpFacade.getResponse().end(); } else { - String uri = binding.redirectBinding(document).requestURI(actionUrl).toString(); + String uri = asRequest ? binding.redirectBinding(document).requestURI(actionUrl).toString() : binding.redirectBinding(document).responseURI(actionUrl).toString(); httpFacade.getResponse().setStatus(302); httpFacade.getResponse().setHeader("Location", uri); + httpFacade.getResponse().end(); } } + } diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/IDP.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/IDP.java index 813f52e0eb..84764e3b4d 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/IDP.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/IDP.java @@ -13,7 +13,6 @@ public class IDP implements Serializable { public static class SingleSignOnService implements Serializable { private boolean signRequest; private boolean validateResponseSignature; - private String signatureCanonicalizationMethod; private String requestBinding; private String responseBinding; private String bindingUrl; @@ -34,14 +33,6 @@ public class IDP implements Serializable { this.validateResponseSignature = validateResponseSignature; } - public String getSignatureCanonicalizationMethod() { - return signatureCanonicalizationMethod; - } - - public void setSignatureCanonicalizationMethod(String signatureCanonicalizationMethod) { - this.signatureCanonicalizationMethod = signatureCanonicalizationMethod; - } - public String getRequestBinding() { return requestBinding; } @@ -72,7 +63,6 @@ public class IDP implements Serializable { private boolean signResponse; private boolean validateRequestSignature; private boolean validateResponseSignature; - private String signatureCanonicalizationMethod; private String requestBinding; private String responseBinding; private String postBindingUrl; @@ -110,14 +100,6 @@ public class IDP implements Serializable { this.validateResponseSignature = validateResponseSignature; } - public String getSignatureCanonicalizationMethod() { - return signatureCanonicalizationMethod; - } - - public void setSignatureCanonicalizationMethod(String signatureCanonicalizationMethod) { - this.signatureCanonicalizationMethod = signatureCanonicalizationMethod; - } - public String getRequestBinding() { return requestBinding; } diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/SP.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/SP.java index addafdb9bf..bd48ba19a6 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/SP.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/SP.java @@ -42,6 +42,8 @@ public class SP implements Serializable { private PrincipalNameMapping principalNameMapping; private Set roleAttributes; private Set roleFriendlyAttributes; + private String signatureAlgorithm; + private String signatureCanonicalizationMethod; private IDP idp; public String getEntityID() { @@ -123,4 +125,20 @@ public class SP implements Serializable { public void setLogoutPage(String logoutPage) { this.logoutPage = logoutPage; } + + public String getSignatureAlgorithm() { + return signatureAlgorithm; + } + + public void setSignatureAlgorithm(String signatureAlgorithm) { + this.signatureAlgorithm = signatureAlgorithm; + } + + public String getSignatureCanonicalizationMethod() { + return signatureCanonicalizationMethod; + } + + public void setSignatureCanonicalizationMethod(String signatureCanonicalizationMethod) { + this.signatureCanonicalizationMethod = signatureCanonicalizationMethod; + } } diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java index a714b0a483..0e0542cf3b 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/ConfigXmlConstants.java @@ -11,6 +11,8 @@ public class ConfigXmlConstants { public static final String SSL_POLICY_ATTR = "sslPolicy"; public static final String NAME_ID_POLICY_FORMAT_ATTR = "nameIDPolicyFormat"; public static final String FORCE_AUTHENTICATION_ATTR = "forceAuthentication"; + public static final String SIGNATURE_ALGORITHM_ATTR = "signatureAlgorithm"; + public static final String SIGNATURE_CANONICALIZATION_METHOD_ATTR = "signatureCanonicalizationMethod"; public static final String LOGOUT_PAGE_ATTR = "logoutPage"; @@ -45,7 +47,6 @@ public class ConfigXmlConstants { public static final String SINGLE_LOGOUT_SERVICE_ELEMENT = "SingleLogoutService"; public static final String SIGN_REQUEST_ATTR = "signRequest"; public static final String SIGN_RESPONSE_ATTR = "signResponse"; - public static final String SIGNATURE_CANONICALIZATION_METHOD_ATTR = "signatureCanonicalizationMethod"; public static final String REQUEST_BINDING_ATTR = "requestBinding"; public static final String RESPONSE_BINDING_ATTR = "responseBinding"; public static final String BINDING_URL_ATTR = "bindingUrl"; diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java index 24f9101fca..46e5b8fdd7 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java @@ -6,6 +6,7 @@ import org.keycloak.adapters.saml.config.Key; import org.keycloak.adapters.saml.config.KeycloakSamlAdapter; import org.keycloak.adapters.saml.config.SP; import org.keycloak.enums.SslRequired; +import org.keycloak.saml.SignatureAlgorithm; import org.keycloak.saml.common.exceptions.ParsingException; import org.keycloak.util.PemUtils; @@ -40,6 +41,11 @@ public class DeploymentBuilder { deployment.setForceAuthentication(sp.isForceAuthentication()); deployment.setNameIDPolicyFormat(sp.getNameIDPolicyFormat()); deployment.setLogoutPage(sp.getLogoutPage()); + deployment.setSignatureCanonicalizationMethod(sp.getSignatureCanonicalizationMethod()); + deployment.setSignatureAlgorithm(SignatureAlgorithm.RSA_SHA256); + if (sp.getSignatureAlgorithm() != null) { + deployment.setSignatureAlgorithm(SignatureAlgorithm.valueOf(sp.getSignatureAlgorithm())); + } if (sp.getPrincipalNameMapping() != null) { SamlDeployment.PrincipalNamePolicy policy = SamlDeployment.PrincipalNamePolicy.valueOf(sp.getPrincipalNameMapping().getPolicy()); deployment.setPrincipalNamePolicy(policy); @@ -51,45 +57,47 @@ public class DeploymentBuilder { SslRequired ssl = SslRequired.valueOf(sp.getSslPolicy()); deployment.setSslRequired(ssl); } - for (Key key : sp.getKeys()) { - if (key.isSigning()) { - PrivateKey privateKey = null; - PublicKey publicKey = null; - if (key.getKeystore() != null) { - KeyStore keyStore = loadKeystore(resourceLoader, key); - Certificate cert = null; - try { - cert = keyStore.getCertificate(key.getKeystore().getCertificateAlias()); - privateKey = (PrivateKey)keyStore.getKey(key.getKeystore().getPrivateKeyAlias(), key.getKeystore().getPrivateKeyPassword().toCharArray()); - } catch (Exception e) { - throw new RuntimeException(e); - } - publicKey = cert.getPublicKey(); - } else { - if (key.getPrivateKeyPem() == null) { - throw new RuntimeException("SP signing key must have a PrivateKey defined"); - } - try { - privateKey = PemUtils.decodePrivateKey(key.getPrivateKeyPem().trim()); - if (key.getPublicKeyPem() == null &&key.getCertificatePem() == null) { - throw new RuntimeException("Sp signing key must have a PublicKey or Certificate defined"); + if (sp.getKeys() != null) { + for (Key key : sp.getKeys()) { + if (key.isSigning()) { + PrivateKey privateKey = null; + PublicKey publicKey = null; + if (key.getKeystore() != null) { + KeyStore keyStore = loadKeystore(resourceLoader, key); + Certificate cert = null; + try { + cert = keyStore.getCertificate(key.getKeystore().getCertificateAlias()); + privateKey = (PrivateKey) keyStore.getKey(key.getKeystore().getPrivateKeyAlias(), key.getKeystore().getPrivateKeyPassword().toCharArray()); + } catch (Exception e) { + throw new RuntimeException(e); } - publicKey = getPublicKeyFromPem(key); + publicKey = cert.getPublicKey(); + } else { + if (key.getPrivateKeyPem() == null) { + throw new RuntimeException("SP signing key must have a PrivateKey defined"); + } + try { + privateKey = PemUtils.decodePrivateKey(key.getPrivateKeyPem().trim()); + if (key.getPublicKeyPem() == null && key.getCertificatePem() == null) { + throw new RuntimeException("Sp signing key must have a PublicKey or Certificate defined"); + } + publicKey = getPublicKeyFromPem(key); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + KeyPair keyPair = new KeyPair(publicKey, privateKey); + deployment.setSigningKeyPair(keyPair); + + } else if (key.isEncryption()) { + KeyStore keyStore = loadKeystore(resourceLoader, key); + try { + PrivateKey privateKey = (PrivateKey) keyStore.getKey(key.getKeystore().getPrivateKeyAlias(), key.getKeystore().getPrivateKeyPassword().toCharArray()); + deployment.setDecryptionKey(privateKey); } catch (Exception e) { throw new RuntimeException(e); } } - KeyPair keyPair = new KeyPair(publicKey, privateKey); - deployment.setSigningKeyPair(keyPair); - - } else if (key.isEncryption()) { - KeyStore keyStore = loadKeystore(resourceLoader, key); - try { - PrivateKey privateKey = (PrivateKey)keyStore.getKey(key.getKeystore().getPrivateKeyAlias(), key.getKeystore().getPrivateKeyPassword().toCharArray()); - deployment.setDecryptionKey(privateKey); - } catch (Exception e) { - throw new RuntimeException(e); - } } } @@ -97,8 +105,9 @@ public class DeploymentBuilder { idp.setEntityID(sp.getIdp().getEntityID()); sso.setRequestBinding(SamlDeployment.Binding.parseBinding(sp.getIdp().getSingleSignOnService().getRequestBinding())); sso.setRequestBindingUrl(sp.getIdp().getSingleSignOnService().getBindingUrl()); - sso.setResponseBinding(SamlDeployment.Binding.parseBinding(sp.getIdp().getSingleSignOnService().getResponseBinding())); - sso.setSignatureCanonicalizationMethod(sp.getIdp().getSingleSignOnService().getSignatureCanonicalizationMethod()); + if (sp.getIdp().getSingleSignOnService().getResponseBinding() != null) { + sso.setResponseBinding(SamlDeployment.Binding.parseBinding(sp.getIdp().getSingleSignOnService().getResponseBinding())); + } sso.setSignRequest(sp.getIdp().getSingleSignOnService().isSignRequest()); sso.setValidateResponseSignature(sp.getIdp().getSingleSignOnService().isValidateResponseSignature()); @@ -106,7 +115,6 @@ public class DeploymentBuilder { slo.setSignResponse(sp.getIdp().getSingleLogoutService().isSignResponse()); slo.setValidateResponseSignature(sp.getIdp().getSingleLogoutService().isValidateResponseSignature()); slo.setValidateRequestSignature(sp.getIdp().getSingleLogoutService().isValidateRequestSignature()); - slo.setSignatureCanonicalizationMethod(sp.getIdp().getSingleLogoutService().getSignatureCanonicalizationMethod()); slo.setRequestBinding(SamlDeployment.Binding.parseBinding(sp.getIdp().getSingleLogoutService().getRequestBinding())); slo.setResponseBinding(SamlDeployment.Binding.parseBinding(sp.getIdp().getSingleLogoutService().getResponseBinding())); if (slo.getRequestBinding() == SamlDeployment.Binding.POST) { @@ -119,26 +127,28 @@ public class DeploymentBuilder { } else { slo.setResponseBindingUrl(sp.getIdp().getSingleLogoutService().getRedirectBindingUrl()); } - for (Key key : sp.getIdp().getKeys()) { - if (key.isSigning()) { - if (key.getKeystore() != null) { - KeyStore keyStore = loadKeystore(resourceLoader, key); - Certificate cert = null; - try { - cert = keyStore.getCertificate(key.getKeystore().getCertificateAlias()); - } catch (KeyStoreException e) { - throw new RuntimeException(e); - } - idp.setSignatureValidationKey(cert.getPublicKey()); - } else { - if (key.getPublicKeyPem() == null && key.getCertificatePem() == null) { - throw new RuntimeException("IDP signing key must have a PublicKey or Certificate defined"); - } - try { - PublicKey publicKey = getPublicKeyFromPem(key); - idp.setSignatureValidationKey(publicKey); - } catch (Exception e) { - throw new RuntimeException(e); + if (sp.getIdp().getKeys() != null) { + for (Key key : sp.getIdp().getKeys()) { + if (key.isSigning()) { + if (key.getKeystore() != null) { + KeyStore keyStore = loadKeystore(resourceLoader, key); + Certificate cert = null; + try { + cert = keyStore.getCertificate(key.getKeystore().getCertificateAlias()); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + idp.setSignatureValidationKey(cert.getPublicKey()); + } else { + if (key.getPublicKeyPem() == null && key.getCertificatePem() == null) { + throw new RuntimeException("IDP signing key must have a PublicKey or Certificate defined"); + } + try { + PublicKey publicKey = getPublicKeyFromPem(key); + idp.setSignatureValidationKey(publicKey); + } catch (Exception e) { + throw new RuntimeException(e); + } } } } diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/IDPXmlParser.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/IDPXmlParser.java index c4e9a6e263..96485d55ef 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/IDPXmlParser.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/IDPXmlParser.java @@ -72,7 +72,6 @@ public class IDPXmlParser extends AbstractParser { slo.setSignRequest(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.SIGN_REQUEST_ATTR)); slo.setValidateResponseSignature(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_RESPONSE_SIGNATURE_ATTR)); slo.setValidateRequestSignature(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_REQUEST_SIGNATURE_ATTR)); - slo.setSignatureCanonicalizationMethod(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.SIGNATURE_CANONICALIZATION_METHOD_ATTR)); slo.setRequestBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.REQUEST_BINDING_ATTR)); slo.setResponseBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.RESPONSE_BINDING_ATTR)); slo.setSignResponse(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.SIGN_RESPONSE_ATTR)); @@ -86,7 +85,6 @@ public class IDPXmlParser extends AbstractParser { StartElement element = StaxParserUtil.getNextStartElement(xmlEventReader); sso.setSignRequest(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.SIGN_REQUEST_ATTR)); sso.setValidateResponseSignature(StaxParserUtil.getBooleanAttributeValue(element, ConfigXmlConstants.VALIDATE_RESPONSE_SIGNATURE_ATTR)); - sso.setSignatureCanonicalizationMethod(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.SIGNATURE_CANONICALIZATION_METHOD_ATTR)); sso.setRequestBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.REQUEST_BINDING_ATTR)); sso.setResponseBinding(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.RESPONSE_BINDING_ATTR)); sso.setBindingUrl(StaxParserUtil.getAttributeValue(element, ConfigXmlConstants.BINDING_URL_ATTR)); diff --git a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/SPXmlParser.java b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/SPXmlParser.java index 8df85001a7..089dc787b5 100755 --- a/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/SPXmlParser.java +++ b/saml/client-adapter/core/src/main/java/org/keycloak/adapters/saml/config/parsers/SPXmlParser.java @@ -37,6 +37,8 @@ public class SPXmlParser extends AbstractParser { sp.setSslPolicy(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.SSL_POLICY_ATTR)); sp.setLogoutPage(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.LOGOUT_PAGE_ATTR)); sp.setNameIDPolicyFormat(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.NAME_ID_POLICY_FORMAT_ATTR)); + sp.setSignatureCanonicalizationMethod(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.SIGNATURE_CANONICALIZATION_METHOD_ATTR)); + sp.setSignatureAlgorithm(StaxParserUtil.getAttributeValue(startElement, ConfigXmlConstants.SIGNATURE_ALGORITHM_ATTR)); sp.setForceAuthentication(StaxParserUtil.getBooleanAttributeValue(startElement, ConfigXmlConstants.FORCE_AUTHENTICATION_ATTR)); while (xmlEventReader.hasNext()) { XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader); diff --git a/saml/client-adapter/core/src/test/java/org/keycloak/test/adapters/saml/XmlParserTest.java b/saml/client-adapter/core/src/test/java/org/keycloak/test/adapters/saml/XmlParserTest.java index 84f03ea65c..c49cdf1f24 100755 --- a/saml/client-adapter/core/src/test/java/org/keycloak/test/adapters/saml/XmlParserTest.java +++ b/saml/client-adapter/core/src/test/java/org/keycloak/test/adapters/saml/XmlParserTest.java @@ -55,7 +55,6 @@ public class XmlParserTest { Assert.assertEquals("idp", idp.getEntityID()); Assert.assertTrue(idp.getSingleSignOnService().isSignRequest()); Assert.assertTrue(idp.getSingleSignOnService().isValidateResponseSignature()); - Assert.assertEquals("canon", idp.getSingleSignOnService().getSignatureCanonicalizationMethod()); Assert.assertEquals("post", idp.getSingleSignOnService().getRequestBinding()); Assert.assertEquals("url", idp.getSingleSignOnService().getBindingUrl()); @@ -63,7 +62,6 @@ public class XmlParserTest { Assert.assertTrue(idp.getSingleLogoutService().isSignResponse()); Assert.assertTrue(idp.getSingleLogoutService().isValidateRequestSignature()); Assert.assertTrue(idp.getSingleLogoutService().isValidateResponseSignature()); - Assert.assertEquals("canon", idp.getSingleLogoutService().getSignatureCanonicalizationMethod()); Assert.assertEquals("redirect", idp.getSingleLogoutService().getRequestBinding()); Assert.assertEquals("post", idp.getSingleLogoutService().getResponseBinding()); Assert.assertEquals("posturl", idp.getSingleLogoutService().getPostBindingUrl()); diff --git a/saml/client-adapter/core/src/test/resources/keycloak-saml.xml b/saml/client-adapter/core/src/test/resources/keycloak-saml.xml index 5755fd7276..c161fa2234 100755 --- a/saml/client-adapter/core/src/test/resources/keycloak-saml.xml +++ b/saml/client-adapter/core/src/test/resources/keycloak-saml.xml @@ -2,6 +2,8 @@ @@ -27,7 +29,6 @@ @@ -37,7 +38,6 @@ validateResponseSignature="true" signRequest="true" signResponse="true" - signatureCanonicalizationMethod="canon" requestBinding="redirect" responseBinding="post" postBindingUrl="posturl" @@ -51,11 +51,5 @@ - - - - - - \ No newline at end of file diff --git a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlAuthMech.java b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlAuthMech.java index cd5253621f..a5a0bd48cf 100755 --- a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlAuthMech.java +++ b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlAuthMech.java @@ -5,6 +5,8 @@ import io.undertow.server.HttpServerExchange; import io.undertow.servlet.handlers.ServletRequestContext; import io.undertow.util.Headers; import org.keycloak.adapters.HttpFacade; +import org.keycloak.adapters.InMemorySessionIdMapper; +import org.keycloak.adapters.SessionIdMapper; import org.keycloak.adapters.saml.SamlDeployment; import org.keycloak.adapters.saml.SamlDeploymentContext; import org.keycloak.adapters.saml.SamlSessionStore; @@ -23,13 +25,14 @@ import java.io.IOException; * @version $Revision: 1 $ */ public class ServletSamlAuthMech extends AbstractSamlAuthMech { + private SessionIdMapper idMapper = new InMemorySessionIdMapper(); public ServletSamlAuthMech(SamlDeploymentContext deploymentContext, UndertowUserSessionManagement sessionManagement, String errorPage) { super(deploymentContext, sessionManagement, errorPage); } @Override protected SamlSessionStore getTokenStore(HttpServerExchange exchange, HttpFacade facade, SamlDeployment deployment, SecurityContext securityContext) { - return new ServletSamlSessionStore(exchange, sessionManagement, securityContext); + return new ServletSamlSessionStore(exchange, sessionManagement, securityContext, idMapper); } @Override diff --git a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java index 696a29c86f..1f32666dc3 100755 --- a/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java +++ b/saml/client-adapter/undertow/src/main/java/org/keycloak/adapters/saml/undertow/ServletSamlSessionStore.java @@ -4,11 +4,13 @@ import io.undertow.security.api.SecurityContext; import io.undertow.security.idm.Account; import io.undertow.server.HttpServerExchange; import io.undertow.server.session.Session; +import io.undertow.server.session.SessionManager; import io.undertow.servlet.handlers.ServletRequestContext; import io.undertow.servlet.spec.HttpSessionImpl; import io.undertow.servlet.util.SavedRequest; import io.undertow.util.Sessions; import org.jboss.logging.Logger; +import org.keycloak.adapters.SessionIdMapper; import org.keycloak.adapters.saml.SamlSession; import org.keycloak.adapters.saml.SamlSessionStore; import org.keycloak.adapters.undertow.UndertowUserSessionManagement; @@ -17,6 +19,8 @@ import org.keycloak.util.KeycloakUriBuilder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.security.Principal; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -31,31 +35,66 @@ public class ServletSamlSessionStore implements SamlSessionStore { private final HttpServerExchange exchange; private final UndertowUserSessionManagement sessionManagement; private final SecurityContext securityContext; + private final SessionIdMapper idMapper; public ServletSamlSessionStore(HttpServerExchange exchange, UndertowUserSessionManagement sessionManagement, - SecurityContext securityContext) { + SecurityContext securityContext, + SessionIdMapper idMapper) { this.exchange = exchange; this.sessionManagement = sessionManagement; this.securityContext = securityContext; + this.idMapper = idMapper; } @Override public void logoutAccount() { HttpSession session = getSession(false); if (session != null) { - session.removeAttribute(SamlSession.class.getName()); + SamlSession samlSession = (SamlSession)session.getAttribute(SamlSession.class.getName()); + if (samlSession != null) { + if (samlSession.getSessionIndex() != null) { + idMapper.removeSession(session.getId()); + } + session.removeAttribute(SamlSession.class.getName()); + } session.removeAttribute(SAML_REDIRECT_URI); } } @Override public void logoutByPrincipal(String principal) { + Set sessions = idMapper.getUserSessions(principal); + if (sessions != null) { + List ids = new LinkedList<>(); + ids.addAll(sessions); + logoutSessionIds(ids); + for (String id : ids) { + idMapper.removeSession(id); + } + } } @Override public void logoutBySsoId(List ssoIds) { + if (ssoIds == null) return; + List sessionIds = new LinkedList<>(); + for (String id : ssoIds) { + String sessionId = idMapper.getSessionFromSSO(id); + if (sessionId != null) { + sessionIds.add(sessionId); + idMapper.removeSession(sessionId); + } + } + logoutSessionIds(sessionIds); + } + + protected void logoutSessionIds(List sessionIds) { + if (sessionIds == null || sessionIds.isEmpty()) return; + final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY); + SessionManager sessionManager = servletRequestContext.getDeployment().getSessionManager(); + sessionManagement.logoutHttpSessions(sessionManager, sessionIds); } @Override @@ -93,6 +132,7 @@ public class ServletSamlSessionStore implements SamlSessionStore { HttpSession session = getSession(true); session.setAttribute(SamlSession.class.getName(), account); sessionManagement.login(servletRequestContext.getDeployment().getSessionManager()); + idMapper.map(account.getSessionIndex(), account.getPrincipal().getSamlSubject(), session.getId()); } diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java index 383e1c5184..d6b745bb43 100755 --- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java +++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java @@ -625,6 +625,7 @@ public class SamlProtocol implements LoginProtocol { SAML2LogoutRequestBuilder logoutBuilder = new SAML2LogoutRequestBuilder() .assertionExpiration(realm.getAccessCodeLifespan()) .issuer(getResponseIssuer(realm)) + .sessionIndex(clientSession.getId()) .userPrincipal(clientSession.getNote(SAML_NAME_ID), clientSession.getNote(SAML_NAME_ID_FORMAT)) .destination(logoutUrl); return logoutBuilder; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlBindingTest.java index 9639aab0f8..429fe81fdd 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlBindingTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/keycloaksaml/SamlBindingTest.java @@ -68,20 +68,20 @@ public class SamlBindingTest { public void initWars() { ClassLoader classLoader = SamlBindingTest.class.getClassLoader(); - //initializeSamlSecuredWar("/keycloak-saml/simple-post", "/sales-post", "post.war", classLoader); + initializeSamlSecuredWar("/keycloak-saml/simple-post", "/sales-post", "post.war", classLoader); initializeSamlSecuredWar("/keycloak-saml/signed-post", "/sales-post-sig", "post-sig.war", classLoader); - //initializeSamlSecuredWar("/keycloak-saml/signed-post-email", "/sales-post-sig-email", "post-sig-email.war", classLoader); - //initializeSamlSecuredWar("/keycloak-saml/signed-post-transient", "/sales-post-sig-transient", "post-sig-transient.war", classLoader); - //initializeSamlSecuredWar("/keycloak-saml/signed-post-persistent", "/sales-post-sig-persistent", "post-sig-persistent.war", classLoader); + initializeSamlSecuredWar("/keycloak-saml/signed-post-email", "/sales-post-sig-email", "post-sig-email.war", classLoader); + initializeSamlSecuredWar("/keycloak-saml/signed-post-transient", "/sales-post-sig-transient", "post-sig-transient.war", classLoader); + initializeSamlSecuredWar("/keycloak-saml/signed-post-persistent", "/sales-post-sig-persistent", "post-sig-persistent.war", classLoader); //initializeSamlSecuredWar("/keycloak-saml/signed-metadata", "/sales-metadata", "post-metadata.war", classLoader); - //initializeSamlSecuredWar("/keycloak-saml/signed-get", "/employee-sig", "employee-sig.war", classLoader); + initializeSamlSecuredWar("/keycloak-saml/signed-get", "/employee-sig", "employee-sig.war", classLoader); //initializeSamlSecuredWar("/saml/simple-get", "/employee", "employee.war", classLoader); - //initializeSamlSecuredWar("/keycloak-saml/signed-front-get", "/employee-sig-front", "employee-sig-front.war", classLoader); + initializeSamlSecuredWar("/keycloak-saml/signed-front-get", "/employee-sig-front", "employee-sig-front.war", classLoader); //initializeSamlSecuredWar("/keycloak-saml/bad-client-signed-post", "/bad-client-sales-post-sig", "bad-client-post-sig.war", classLoader); //initializeSamlSecuredWar("/keycloak-saml/bad-realm-signed-post", "/bad-realm-sales-post-sig", "bad-realm-post-sig.war", classLoader); //initializeSamlSecuredWar("/keycloak-saml/encrypted-post", "/sales-post-enc", "post-enc.war", classLoader); //uploadSP(); - //server.getServer().deploy(createDeploymentInfo("employee.war", "/employee", SamlSPFacade.class)); + server.getServer().deploy(createDeploymentInfo("employee.war", "/employee", SamlSPFacade.class)); @@ -411,7 +411,8 @@ public class SamlBindingTest { driver.navigate().to("http://localhost:8081/employee-sig?GLO=true"); checkLoggedOut("http://localhost:8081/employee-sig/"); driver.navigate().to("http://localhost:8081/employee-sig-front/"); - Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml")); + String currentUrl = driver.getCurrentUrl(); + Assert.assertTrue(currentUrl.startsWith("http://localhost:8081/auth/realms/demo/protocol/saml")); driver.navigate().to("http://localhost:8081/sales-post-sig/"); Assert.assertTrue(driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml")); @@ -505,6 +506,4 @@ public class SamlBindingTest { response.close(); client.close(); } - - } diff --git a/testsuite/integration/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keycloak-saml.xml b/testsuite/integration/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keycloak-saml.xml new file mode 100755 index 0000000000..51c8e0cff1 --- /dev/null +++ b/testsuite/integration/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keycloak-saml.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keystore.jks b/testsuite/integration/src/test/resources/keycloak-saml/signed-front-get/WEB-INF/keystore.jks new file mode 100755 index 0000000000000000000000000000000000000000..4daad218a3f78b798d1de8996c39014785c45c95 GIT binary patch literal 1701 zcmezO_TO6u1_mZ5W@J##C@Cqh($~+)PfpCq$S*FjvM{hP&`-@R$jPrvP1P;VOxI^% zVDyw<_*fUHZ?{1c({=+sHZE;8MixdbCP79uyORg)YY z9JblVoe37#<8yv++uHrwMt(`Nphxp#7ED_>S+vq3A$V?CM$x=F8~<1CpSc$wm(+Hu zz411`BD+=kz1b=gKRL;#`#Nn7@#d5Jgp zyU+bqJSg}`^iOo zwxaAnwr1v=(`8HSvI0&q#(LVmKj`48_o=|ZF~sUz-)ZfXQ}aKUYj?g;S+jPLZ2MC8 zEpA)iUwZXc@|w-v(2Mr_Po{d<9q;Y+%6pbo7@Xb3k?m22G3?fY_3W4Vb!TZxJxyW#iOp z^Jx3d%gD&h%3z>psAHhT#vIDREKE!$F_07IH8e3aFf=!`G&VN1h!W>Df^kiaEuu&^ zuW>%Ii-6gTxv`hQps|ywv5{flH`fH4sGK&FZJD+Uo@ZwH{aw0pZ*tSun_+&BMB=y^ z-c2e|JryhF@lboSqNJ$VMAPivsn=Wtr>-(y5UJYq_2(w@J=?sZzH4Uv+~XE=KG0oV z%k6FBuhuEy8?;t$$hlZO_hNdxV@r%s!{Sv3y`=Sau5!A_d*%0qkdsYQ+P9rwz|X|Y z$iRr~JYaw^1Kp*x$!6m!!+N$2U59F>+Ehlq%vy6f=7g$ll>JAT@7R&GCYog$eH$nhLh>b-VWDfl~L?*gnZUEWO_nVto$@tppcqEGenE`Oq>; z4-w&0fssAYpz$|2zEk#1MRUFZzag&yHzdBnCLl$q1u#O*5D{u&Y-(&4g{c8wjI9pa zu+Hy-b{^ZzGkX*F$r^6imsY&X#BA}^xvfw1e#jhB*v@8j>~OT3Ko)0a!8^|-sngn? zJuh->vnjvpod0{y|A2!#CTlxJOT?K5E!SVTU{!Eb&au{-Pv<$}RhXETZ_@i~a>{Q0 zqUE0b5|y6wihq^uGu~!qEyNfuCde$>GWV-Kt{Bt!8Ol`uIwkVrY6hQMG0Vc--|c@> z_11Di$61H3Yb+f~Hfi3Uxw>}!`N=XhR-HG~JPhu~3%XW))cNBg+UGy3J|?IC()^$P zzJ;ylddv2%TfF-1tBtIV-#1IRPC2=Ef||6-p*3ssE@!Cj<9MC20gXI3Dk|qo%RL%nc;dRUo literal 0 HcmV?d00001 diff --git a/testsuite/integration/src/test/resources/keycloak-saml/signed-get/WEB-INF/keycloak-saml.xml b/testsuite/integration/src/test/resources/keycloak-saml/signed-get/WEB-INF/keycloak-saml.xml new file mode 100755 index 0000000000..909216d7f9 --- /dev/null +++ b/testsuite/integration/src/test/resources/keycloak-saml/signed-get/WEB-INF/keycloak-saml.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration/src/test/resources/keycloak-saml/signed-get/WEB-INF/keystore.jks b/testsuite/integration/src/test/resources/keycloak-saml/signed-get/WEB-INF/keystore.jks new file mode 100755 index 0000000000000000000000000000000000000000..4daad218a3f78b798d1de8996c39014785c45c95 GIT binary patch literal 1701 zcmezO_TO6u1_mZ5W@J##C@Cqh($~+)PfpCq$S*FjvM{hP&`-@R$jPrvP1P;VOxI^% zVDyw<_*fUHZ?{1c({=+sHZE;8MixdbCP79uyORg)YY z9JblVoe37#<8yv++uHrwMt(`Nphxp#7ED_>S+vq3A$V?CM$x=F8~<1CpSc$wm(+Hu zz411`BD+=kz1b=gKRL;#`#Nn7@#d5Jgp zyU+bqJSg}`^iOo zwxaAnwr1v=(`8HSvI0&q#(LVmKj`48_o=|ZF~sUz-)ZfXQ}aKUYj?g;S+jPLZ2MC8 zEpA)iUwZXc@|w-v(2Mr_Po{d<9q;Y+%6pbo7@Xb3k?m22G3?fY_3W4Vb!TZxJxyW#iOp z^Jx3d%gD&h%3z>psAHhT#vIDREKE!$F_07IH8e3aFf=!`G&VN1h!W>Df^kiaEuu&^ zuW>%Ii-6gTxv`hQps|ywv5{flH`fH4sGK&FZJD+Uo@ZwH{aw0pZ*tSun_+&BMB=y^ z-c2e|JryhF@lboSqNJ$VMAPivsn=Wtr>-(y5UJYq_2(w@J=?sZzH4Uv+~XE=KG0oV z%k6FBuhuEy8?;t$$hlZO_hNdxV@r%s!{Sv3y`=Sau5!A_d*%0qkdsYQ+P9rwz|X|Y z$iRr~JYaw^1Kp*x$!6m!!+N$2U59F>+Ehlq%vy6f=7g$ll>JAT@7R&GCYog$eH$nhLh>b-VWDfl~L?*gnZUEWO_nVto$@tppcqEGenE`Oq>; z4-w&0fssAYpz$|2zEk#1MRUFZzag&yHzdBnCLl$q1u#O*5D{u&Y-(&4g{c8wjI9pa zu+Hy-b{^ZzGkX*F$r^6imsY&X#BA}^xvfw1e#jhB*v@8j>~OT3Ko)0a!8^|-sngn? zJuh->vnjvpod0{y|A2!#CTlxJOT?K5E!SVTU{!Eb&au{-Pv<$}RhXETZ_@i~a>{Q0 zqUE0b5|y6wihq^uGu~!qEyNfuCde$>GWV-Kt{Bt!8Ol`uIwkVrY6hQMG0Vc--|c@> z_11Di$61H3Yb+f~Hfi3Uxw>}!`N=XhR-HG~JPhu~3%XW))cNBg+UGy3J|?IC()^$P zzJ;ylddv2%TfF-1tBtIV-#1IRPC2=Ef||6-p*3ssE@!Cj<9MC20gXI3Dk|qo%RL%nc;dRUo literal 0 HcmV?d00001 diff --git a/testsuite/integration/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keycloak-saml.xml b/testsuite/integration/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keycloak-saml.xml new file mode 100755 index 0000000000..ef9856a4b2 --- /dev/null +++ b/testsuite/integration/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keycloak-saml.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keystore.jks b/testsuite/integration/src/test/resources/keycloak-saml/signed-post-email/WEB-INF/keystore.jks new file mode 100755 index 0000000000000000000000000000000000000000..144830bc77683d1d0a3d29f8793471d4f395bdb0 GIT binary patch literal 1705 zcmezO_TO6u1_mZ5W@J#!C@Cqh($~+)PfpCq$S*FjvM{hP&@WERNiEhb0P=N1M z7#KYz`B=UJb?!81V%loJ$Ht}2#>m2`#U#kc$jZRd#I(>@`_HHQr3*BE{x`hDyEHld z+K~ja7y5T|r=%}Fu;`1zi=v(re>&z=o_dkol)j+zYO>t=Qy1S}v3en%vP3563G;>m zf%$6H#y=LWo_E+v&g1u@xzTso16CaPbkO_D8o@;(`MobV^Igq3BNxZ5w|jA2W>>?O zsK)o5D^C2naN_4wlZOiFZx$ZYW2t4}JhWx=_GhgLGruICtx3+%d3V!9>Dt7nXAhlc z$;{X;mJr8NzU5%3ud}q*;Tc<&7_HRg&F#_Q?wWFKHOG|)@xdBe`K>+ek+V}K-){E) zl)cDAKzFrg_KD*rPhJ#0xY%188oeS%DBgct!6JRDwVn#urq)k%GX7O$-%BXGHp?M$ zPK(%~JsS=itGtnGNeXRIJS=enoqTH}>U?=&w0Rv-!V zt0IaI7=L{C`R*=P35_m^|6)DbnI1Rom?{^itz&v>PMs${YwWF4+mV{{ zB3p#_4CDJAHQ!e4#HZJ%dA%($R{WrMXd~~o9sJ4l4<@p_UZ&<;=%+j9w)>u?FXr2x z;Qi$;R(a*~n?JwFjfqj;bam5w#iu)2cStlBuRNH-DYCa*SFTj`Ruc2O%^{1v zS^p3Un$kT>@>nGEyG?KA#5`*A-Q)TDd5mCQN4nqL|I4L=R^IMCEM*}Xua~%r;rLwD z(rqehS=sAVMB2P;SIyh9w+fi%85vk3^h^ybfvg(_O^jE7*p`Wn(Np4IY>ELd8>d#A zN85K^Mn-N{1_J{_Jp&y!=1>-9Vd650ft)z6p^2e^p_!qPiHVVMlsK;ujB93K97TqS zjq{OR1z|$TGQU@sN$9wB)LN$MwU<2= zd)SlRE7$3UyG=O%*+B2uv-3&H4597J6WaBsZpb_&f7j)l$IXYTF6-xcsr5`yWnyMz zU_^EvFwmHR?&_X(ZsE4#TgmHFu2rXfU6s0)lCKe^<7iiUsaqK$zd9h>c57vO3iO-78%EoLL<8ZmZxNJeq&U-KBw5j(T{eI-t zj}(o0{2w&pRSxr|MK;+T;phADf{DX@d*|wohzX72{tZ3*&sbbC2N!KDDXF>n@KOsN z=~ICbKGC4@Hz>{}*<-lToNvHy$ZNn2iF2?C$Wdx)Vu&22rlzLAD8`N=&Wn#AY>fF{RdOu_iDQssmI(9hPO(2Uiv*4ZQlGJH!&z=`K zw%L^5bkqb1@@gO=+rT(BxQD(6^h&8PDm@hVJA%Qxx$H92KBf6;Q! zeu+xYdBwlV_8D(8vle0u7ZYR_ZJGO3A6Ja^r!9<;Jf^6B_V*`!pI4_%{2#46Qrcoa z{d4O3!wr>pceY+y88$ipliuM2X9G4KozS*BUZS)4a=%Gc^OV}R*}*rh8m{{;m0Oa) z^Ysn?xlP?KeF94gT3Fr`zuJ}MUVH6cw8xR2&A~UG*V~pyDQR4_ymoT_iPrx=pDW$^ gV7obl)$b?cUQd>i8HM*{tk@@=IXfvlri|w}0JG8182|tP literal 0 HcmV?d00001 diff --git a/testsuite/integration/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keycloak-saml.xml b/testsuite/integration/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keycloak-saml.xml new file mode 100755 index 0000000000..7bc05f6593 --- /dev/null +++ b/testsuite/integration/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keycloak-saml.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keystore.jks b/testsuite/integration/src/test/resources/keycloak-saml/signed-post-persistent/WEB-INF/keystore.jks new file mode 100755 index 0000000000000000000000000000000000000000..144830bc77683d1d0a3d29f8793471d4f395bdb0 GIT binary patch literal 1705 zcmezO_TO6u1_mZ5W@J#!C@Cqh($~+)PfpCq$S*FjvM{hP&@WERNiEhb0P=N1M z7#KYz`B=UJb?!81V%loJ$Ht}2#>m2`#U#kc$jZRd#I(>@`_HHQr3*BE{x`hDyEHld z+K~ja7y5T|r=%}Fu;`1zi=v(re>&z=o_dkol)j+zYO>t=Qy1S}v3en%vP3563G;>m zf%$6H#y=LWo_E+v&g1u@xzTso16CaPbkO_D8o@;(`MobV^Igq3BNxZ5w|jA2W>>?O zsK)o5D^C2naN_4wlZOiFZx$ZYW2t4}JhWx=_GhgLGruICtx3+%d3V!9>Dt7nXAhlc z$;{X;mJr8NzU5%3ud}q*;Tc<&7_HRg&F#_Q?wWFKHOG|)@xdBe`K>+ek+V}K-){E) zl)cDAKzFrg_KD*rPhJ#0xY%188oeS%DBgct!6JRDwVn#urq)k%GX7O$-%BXGHp?M$ zPK(%~JsS=itGtnGNeXRIJS=enoqTH}>U?=&w0Rv-!V zt0IaI7=L{C`R*=P35_m^|6)DbnI1Rom?{^itz&v>PMs${YwWF4+mV{{ zB3p#_4CDJAHQ!e4#HZJ%dA%($R{WrMXd~~o9sJ4l4<@p_UZ&<;=%+j9w)>u?FXr2x z;Qi$;R(a*~n?JwFjfqj;bam5w#iu)2cStlBuRNH-DYCa*SFTj`Ruc2O%^{1v zS^p3Un$kT>@>nGEyG?KA#5`*A-Q)TDd5mCQN4nqL|I4L=R^IMCEM*}Xua~%r;rLwD z(rqehS=sAVMB2P;SIyh9w+fi%85vk3^h^ybfvg(_O^jE7*p`Wn(Np4IY>ELd8>d#A zN85K^Mn-N{1_J{_Jp&y!=1>-9Vd650ft)z6p^2e^p_!qPiHVVMlsK;ujB93K97TqS zjq{OR1z|$TGQU@sN$9wB)LN$MwU<2= zd)SlRE7$3UyG=O%*+B2uv-3&H4597J6WaBsZpb_&f7j)l$IXYTF6-xcsr5`yWnyMz zU_^EvFwmHR?&_X(ZsE4#TgmHFu2rXfU6s0)lCKe^<7iiUsaqK$zd9h>c57vO3iO-78%EoLL<8ZmZxNJeq&U-KBw5j(T{eI-t zj}(o0{2w&pRSxr|MK;+T;phADf{DX@d*|wohzX72{tZ3*&sbbC2N!KDDXF>n@KOsN z=~ICbKGC4@Hz>{}*<-lToNvHy$ZNn2iF2?C$Wdx)Vu&22rlzLAD8`N=&Wn#AY>fF{RdOu_iDQssmI(9hPO(2Uiv*4ZQlGJH!&z=`K zw%L^5bkqb1@@gO=+rT(BxQD(6^h&8PDm@hVJA%Qxx$H92KBf6;Q! zeu+xYdBwlV_8D(8vle0u7ZYR_ZJGO3A6Ja^r!9<;Jf^6B_V*`!pI4_%{2#46Qrcoa z{d4O3!wr>pceY+y88$ipliuM2X9G4KozS*BUZS)4a=%Gc^OV}R*}*rh8m{{;m0Oa) z^Ysn?xlP?KeF94gT3Fr`zuJ}MUVH6cw8xR2&A~UG*V~pyDQR4_ymoT_iPrx=pDW$^ gV7obl)$b?cUQd>i8HM*{tk@@=IXfvlri|w}0JG8182|tP literal 0 HcmV?d00001 diff --git a/testsuite/integration/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keycloak-saml.xml b/testsuite/integration/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keycloak-saml.xml new file mode 100755 index 0000000000..5d614faf93 --- /dev/null +++ b/testsuite/integration/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keycloak-saml.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keystore.jks b/testsuite/integration/src/test/resources/keycloak-saml/signed-post-transient/WEB-INF/keystore.jks new file mode 100755 index 0000000000000000000000000000000000000000..144830bc77683d1d0a3d29f8793471d4f395bdb0 GIT binary patch literal 1705 zcmezO_TO6u1_mZ5W@J#!C@Cqh($~+)PfpCq$S*FjvM{hP&@WERNiEhb0P=N1M z7#KYz`B=UJb?!81V%loJ$Ht}2#>m2`#U#kc$jZRd#I(>@`_HHQr3*BE{x`hDyEHld z+K~ja7y5T|r=%}Fu;`1zi=v(re>&z=o_dkol)j+zYO>t=Qy1S}v3en%vP3563G;>m zf%$6H#y=LWo_E+v&g1u@xzTso16CaPbkO_D8o@;(`MobV^Igq3BNxZ5w|jA2W>>?O zsK)o5D^C2naN_4wlZOiFZx$ZYW2t4}JhWx=_GhgLGruICtx3+%d3V!9>Dt7nXAhlc z$;{X;mJr8NzU5%3ud}q*;Tc<&7_HRg&F#_Q?wWFKHOG|)@xdBe`K>+ek+V}K-){E) zl)cDAKzFrg_KD*rPhJ#0xY%188oeS%DBgct!6JRDwVn#urq)k%GX7O$-%BXGHp?M$ zPK(%~JsS=itGtnGNeXRIJS=enoqTH}>U?=&w0Rv-!V zt0IaI7=L{C`R*=P35_m^|6)DbnI1Rom?{^itz&v>PMs${YwWF4+mV{{ zB3p#_4CDJAHQ!e4#HZJ%dA%($R{WrMXd~~o9sJ4l4<@p_UZ&<;=%+j9w)>u?FXr2x z;Qi$;R(a*~n?JwFjfqj;bam5w#iu)2cStlBuRNH-DYCa*SFTj`Ruc2O%^{1v zS^p3Un$kT>@>nGEyG?KA#5`*A-Q)TDd5mCQN4nqL|I4L=R^IMCEM*}Xua~%r;rLwD z(rqehS=sAVMB2P;SIyh9w+fi%85vk3^h^ybfvg(_O^jE7*p`Wn(Np4IY>ELd8>d#A zN85K^Mn-N{1_J{_Jp&y!=1>-9Vd650ft)z6p^2e^p_!qPiHVVMlsK;ujB93K97TqS zjq{OR1z|$TGQU@sN$9wB)LN$MwU<2= zd)SlRE7$3UyG=O%*+B2uv-3&H4597J6WaBsZpb_&f7j)l$IXYTF6-xcsr5`yWnyMz zU_^EvFwmHR?&_X(ZsE4#TgmHFu2rXfU6s0)lCKe^<7iiUsaqK$zd9h>c57vO3iO-78%EoLL<8ZmZxNJeq&U-KBw5j(T{eI-t zj}(o0{2w&pRSxr|MK;+T;phADf{DX@d*|wohzX72{tZ3*&sbbC2N!KDDXF>n@KOsN z=~ICbKGC4@Hz>{}*<-lToNvHy$ZNn2iF2?C$Wdx)Vu&22rlzLAD8`N=&Wn#AY>fF{RdOu_iDQssmI(9hPO(2Uiv*4ZQlGJH!&z=`K zw%L^5bkqb1@@gO=+rT(BxQD(6^h&8PDm@hVJA%Qxx$H92KBf6;Q! zeu+xYdBwlV_8D(8vle0u7ZYR_ZJGO3A6Ja^r!9<;Jf^6B_V*`!pI4_%{2#46Qrcoa z{d4O3!wr>pceY+y88$ipliuM2X9G4KozS*BUZS)4a=%Gc^OV}R*}*rh8m{{;m0Oa) z^Ysn?xlP?KeF94gT3Fr`zuJ}MUVH6cw8xR2&A~UG*V~pyDQR4_ymoT_iPrx=pDW$^ gV7obl)$b?cUQd>i8HM*{tk@@=IXfvlri|w}0JG8182|tP literal 0 HcmV?d00001 diff --git a/testsuite/integration/src/test/resources/keycloak-saml/simple-post/WEB-INF/keycloak-saml.xml b/testsuite/integration/src/test/resources/keycloak-saml/simple-post/WEB-INF/keycloak-saml.xml new file mode 100755 index 0000000000..501e8f5b40 --- /dev/null +++ b/testsuite/integration/src/test/resources/keycloak-saml/simple-post/WEB-INF/keycloak-saml.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json b/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json index e929c24ac7..c6b682dc02 100755 --- a/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json +++ b/testsuite/integration/src/test/resources/keycloak-saml/testsaml.json @@ -209,7 +209,7 @@ "attributes": { "saml.server.signature": "true", "saml.client.signature": "true", - "saml.signature.algorithm": "RSA_SHA1", + "saml.signature.algorithm": "RSA_SHA256", "saml.authnstatement": "true", "saml.signing.certificate": "MIIB0DCCATkCBgFJH5u0EDANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNodHRwOi8vbG9jYWxob3N0OjgwODAvZW1wbG95ZWUtc2lnLzAeFw0xNDEwMTcxOTMzNThaFw0yNDEwMTcxOTM1MzhaMC4xLDAqBgNVBAMTI2h0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9lbXBsb3llZS1zaWcvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+9kVgPFpshjS2aT2g52lqTv2lqb1jgvXZVk7iFF4LAO6SdCXKXRZI4SuzIRkVNpE1a42V1kQRlaozoFklgvX5sje8tkpa9ylq+bxGXM9RRycqRu2B+oWUV7Aqq7Bs0Xud0WeHQYRcEoCjqsFKGy65qkLRDdT70FTJgpSHts+gDwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACKyPLGqMX8GsIrCfJU8eVnpaqzTXMglLVo/nTcfAnWe9UAdVe8N3a2PXpDBvuqNA/DEAhVcQgxdlOTWnB6s8/yLTRuH0bZgb3qGdySif+lU+E7zZ/SiDzavAvn+ABqemnzHcHyhYO+hNRGHvUbW5OAii9Vdjhm8BI32YF1NwhKp" }