diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2LogoutRequestBuilder.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2LogoutRequestBuilder.java index 045b318cb6..9e885ea658 100755 --- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2LogoutRequestBuilder.java +++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SAML2LogoutRequestBuilder.java @@ -22,9 +22,11 @@ import java.net.URI; */ public class SAML2LogoutRequestBuilder extends SAML2BindingBuilder { protected String userPrincipal; + protected String userPrincipalFormat; - public SAML2LogoutRequestBuilder userPrincipal(String userPrincipal) { - this.userPrincipal = userPrincipal; + public SAML2LogoutRequestBuilder userPrincipal(String nameID, String nameIDformat) { + this.userPrincipal = nameID; + this.userPrincipalFormat = nameIDformat; return this; } @@ -51,7 +53,7 @@ public class SAML2LogoutRequestBuilder extends SAML2BindingBuilderBill Burke @@ -54,7 +55,10 @@ public class SamlProtocol implements LoginProtocol { public static final String SAML_ENCRYPT = "saml.encrypt"; public static final String SAML_FORCE_POST_BINDING = "saml.force.post.binding"; public static final String SAML_REQUEST_ID = "SAML_REQUEST_ID"; + public static final String SAML_NAME_ID = "SAML_NAME_ID"; + public static final String SAML_NAME_ID_FORMAT = "SAML_NAME_ID_FORMAT"; public static final String SAML_DEFAULT_NAMEID_FORMAT = JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get(); + public static final String SAML_PERSISTENT_NAME_ID_FOR = "saml.persistent.name.id.for"; protected KeycloakSession session; @@ -125,12 +129,25 @@ public class SamlProtocol implements LoginProtocol { } protected String getNameId(String nameIdFormat, ClientSessionModel clientSession, UserSessionModel userSession) { - if(nameIdFormat.equals(JBossSAMLURIConstants.NAMEID_FORMAT_EMAIL.get())) { + if (nameIdFormat.equals(JBossSAMLURIConstants.NAMEID_FORMAT_EMAIL.get())) { return userSession.getUser().getEmail(); } else if(nameIdFormat.equals(JBossSAMLURIConstants.NAMEID_FORMAT_TRANSIENT.get())) { + // "G-" stands for "generated" Add this for the slight possibility of collisions. + return "G-" + UUID.randomUUID().toString(); + } else if(nameIdFormat.equals(JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get())) { + // generate a persistent user id specifically for each client. + UserModel user = userSession.getUser(); + String name = SAML_PERSISTENT_NAME_ID_FOR + "." + clientSession.getClient().getClientId(); + String samlPersistentId = user.getAttribute(name); + if (samlPersistentId != null) return samlPersistentId; + // "G-" stands for "generated" + samlPersistentId = "G-" + UUID.randomUUID().toString(); + user.setAttribute(name, samlPersistentId); + return samlPersistentId; + } else if(nameIdFormat.equals(JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get())){ + // TODO: Support for persistent NameID (pseudo-random identifier persisted in user object) return userSession.getUser().getUsername(); } else { - // TODO: Support for persistent NameID (pseudo-random identifier persisted in user object) return userSession.getUser().getUsername(); } } @@ -146,6 +163,11 @@ public class SamlProtocol implements LoginProtocol { String nameIdFormat = getNameIdFormat(clientSession); String nameId = getNameId(nameIdFormat, clientSession, userSession); + // save NAME_ID and format in clientSession as they may be persistent or transient or email and not username + // we'll need to send this back on a logout + clientSession.setNote(SAML_NAME_ID, nameId); + clientSession.setNote(SAML_NAME_ID_FORMAT, nameIdFormat); + SALM2LoginResponseBuilder builder = new SALM2LoginResponseBuilder(); builder.requestID(requestID) .relayState(relayState) @@ -256,8 +278,9 @@ public class SamlProtocol implements LoginProtocol { ApplicationModel app = (ApplicationModel)client; if (app.getManagementUrl() == null) return; + // build userPrincipal with subject used at login SAML2LogoutRequestBuilder logoutBuilder = new SAML2LogoutRequestBuilder() - .userPrincipal(userSession.getUser().getUsername()) + .userPrincipal(clientSession.getNote(SAML_NAME_ID), clientSession.getNote(SAML_NAME_ID_FORMAT)) .destination(client.getClientId()); if (requiresRealmSignature(client)) { logoutBuilder.signatureAlgorithm(getSignatureAlgorithm(client)) diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java index 8d542bf229..2ad6584266 100755 --- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java +++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlService.java @@ -246,6 +246,7 @@ public class SamlService { private boolean isSupportedNameIdFormat(String nameIdFormat) { if (nameIdFormat.equals(JBossSAMLURIConstants.NAMEID_FORMAT_EMAIL.get()) || nameIdFormat.equals(JBossSAMLURIConstants.NAMEID_FORMAT_TRANSIENT.get()) || + nameIdFormat.equals(JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get()) || nameIdFormat.equals(JBossSAMLURIConstants.NAMEID_FORMAT_UNSPECIFIED.get())) { return true; } diff --git a/saml/saml-protocol/src/main/resources/idp-metadata-template.xml b/saml/saml-protocol/src/main/resources/idp-metadata-template.xml index 25455c06fc..bc667d1e58 100755 --- a/saml/saml-protocol/src/main/resources/idp-metadata-template.xml +++ b/saml/saml-protocol/src/main/resources/idp-metadata-template.xml @@ -5,7 +5,8 @@ - urn:oasis:names:tc:SAML:2.0:nameid-format:transient + urn:oasis:names:tc:SAML:2.0:nameid-format:persistent + urn:oasis:names:tc:SAML:2.0:nameid-format:transient urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java index 94d65ad8dc..b796452f93 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlBindingTest.java @@ -49,6 +49,9 @@ public class SamlBindingTest { initializeSamlSecuredWar("/saml/simple-post", "/sales-post", "post.war", classLoader); initializeSamlSecuredWar("/saml/signed-post", "/sales-post-sig", "post-sig.war", classLoader); + initializeSamlSecuredWar("/saml/signed-post-email", "/sales-post-sig-email", "post-sig-email.war", classLoader); + initializeSamlSecuredWar("/saml/signed-post-transient", "/sales-post-sig-transient", "post-sig-transient.war", classLoader); + initializeSamlSecuredWar("/saml/signed-post-persistent", "/sales-post-sig-persistent", "post-sig-persistent.war", classLoader); initializeSamlSecuredWar("/saml/signed-metadata", "/sales-metadata", "post-metadata.war", classLoader); initializeSamlSecuredWar("/saml/signed-get", "/employee-sig", "employee-sig.war", classLoader); initializeSamlSecuredWar("/saml/bad-client-signed-post", "/bad-client-sales-post-sig", "bad-client-post-sig.war", classLoader); @@ -99,6 +102,44 @@ public class SamlBindingTest { driver.navigate().to("http://localhost:8081/sales-post-sig?GLO=true"); Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml"); + } + @Test + public void testPostSignedLoginLogoutTransientNameID() { + driver.navigate().to("http://localhost:8081/sales-post-sig-transient/"); + Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml"); + loginPage.login("bburke", "password"); + Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-transient/"); + System.out.println(driver.getPageSource()); + Assert.assertFalse(driver.getPageSource().contains("bburke")); + Assert.assertTrue(driver.getPageSource().contains("principal=G-")); + driver.navigate().to("http://localhost:8081/sales-post-sig-transient?GLO=true"); + Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml"); + + } + @Test + public void testPostSignedLoginLogoutPersistentNameID() { + driver.navigate().to("http://localhost:8081/sales-post-sig-persistent/"); + Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml"); + loginPage.login("bburke", "password"); + Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-persistent/"); + System.out.println(driver.getPageSource()); + Assert.assertFalse(driver.getPageSource().contains("bburke")); + Assert.assertTrue(driver.getPageSource().contains("principal=G-")); + driver.navigate().to("http://localhost:8081/sales-post-sig-persistent?GLO=true"); + Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml"); + + } + @Test + public void testPostSignedLoginLogoutEmailNameID() { + driver.navigate().to("http://localhost:8081/sales-post-sig-email/"); + Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml"); + loginPage.login("bburke", "password"); + Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-email/"); + System.out.println(driver.getPageSource()); + Assert.assertTrue(driver.getPageSource().contains("principal=bburke@redhat.com")); + driver.navigate().to("http://localhost:8081/sales-post-sig-email?GLO=true"); + Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml"); + } @Test public void testRedirectSignedLoginLogout() { diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlKeycloakRule.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlKeycloakRule.java index 349f7393cb..f3b543ff34 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlKeycloakRule.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/saml/SamlKeycloakRule.java @@ -36,6 +36,7 @@ public abstract class SamlKeycloakRule extends AbstractKeycloakRule { resp.setContentType("text/plain"); OutputStream stream = resp.getOutputStream(); Principal principal = req.getUserPrincipal(); + stream.write("principal=".getBytes()); if (principal == null) { stream.write("null".getBytes()); return; @@ -48,6 +49,7 @@ public abstract class SamlKeycloakRule extends AbstractKeycloakRule { resp.setContentType("text/plain"); OutputStream stream = resp.getOutputStream(); Principal principal = req.getUserPrincipal(); + stream.write("principal=".getBytes()); if (principal == null) { stream.write("null".getBytes()); return; diff --git a/testsuite/integration/src/test/resources/saml/encrypted-post/WEB-INF/picketlink.xml b/testsuite/integration/src/test/resources/saml/encrypted-post/WEB-INF/picketlink.xml index 068d3ecfe5..b028a394c7 100755 --- a/testsuite/integration/src/test/resources/saml/encrypted-post/WEB-INF/picketlink.xml +++ b/testsuite/integration/src/test/resources/saml/encrypted-post/WEB-INF/picketlink.xml @@ -19,8 +19,10 @@ - + + - + + - + + + + ${idp-sig.url::http://localhost:8081/auth/realms/demo/protocol/saml} + + ${sales-post-sig.url::http://localhost:8081/sales-post-sig-email/} + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/integration/src/test/resources/saml/signed-post-persistent/WEB-INF/keystore.jks b/testsuite/integration/src/test/resources/saml/signed-post-persistent/WEB-INF/keystore.jks new file mode 100755 index 0000000000..144830bc77 Binary files /dev/null and b/testsuite/integration/src/test/resources/saml/signed-post-persistent/WEB-INF/keystore.jks differ diff --git a/testsuite/integration/src/test/resources/saml/signed-post-persistent/WEB-INF/picketlink.xml b/testsuite/integration/src/test/resources/saml/signed-post-persistent/WEB-INF/picketlink.xml new file mode 100755 index 0000000000..2a57b17da1 --- /dev/null +++ b/testsuite/integration/src/test/resources/saml/signed-post-persistent/WEB-INF/picketlink.xml @@ -0,0 +1,33 @@ + + + ${idp-sig.url::http://localhost:8081/auth/realms/demo/protocol/saml} + + ${sales-post-sig.url::http://localhost:8081/sales-post-sig-persistent/} + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/integration/src/test/resources/saml/signed-post-transient/WEB-INF/keystore.jks b/testsuite/integration/src/test/resources/saml/signed-post-transient/WEB-INF/keystore.jks new file mode 100755 index 0000000000..144830bc77 Binary files /dev/null and b/testsuite/integration/src/test/resources/saml/signed-post-transient/WEB-INF/keystore.jks differ diff --git a/testsuite/integration/src/test/resources/saml/signed-post-transient/WEB-INF/picketlink.xml b/testsuite/integration/src/test/resources/saml/signed-post-transient/WEB-INF/picketlink.xml new file mode 100755 index 0000000000..70d81fca73 --- /dev/null +++ b/testsuite/integration/src/test/resources/saml/signed-post-transient/WEB-INF/picketlink.xml @@ -0,0 +1,33 @@ + + + ${idp-sig.url::http://localhost:8081/auth/realms/demo/protocol/saml} + + ${sales-post-sig.url::http://localhost:8081/sales-post-sig-transient/} + + + + + + + + + + + + + + + + + + + + diff --git a/testsuite/integration/src/test/resources/saml/signed-post/WEB-INF/picketlink.xml b/testsuite/integration/src/test/resources/saml/signed-post/WEB-INF/picketlink.xml index 39ea93555e..31011dbbe5 100755 --- a/testsuite/integration/src/test/resources/saml/signed-post/WEB-INF/picketlink.xml +++ b/testsuite/integration/src/test/resources/saml/signed-post/WEB-INF/picketlink.xml @@ -1,31 +1,33 @@ - - ${idp-sig.url::http://localhost:8081/auth/realms/demo/protocol/saml} - - ${sales-post-sig.url::http://localhost:8081/sales-post-sig/} - - - - - - - - - + + ${idp-sig.url::http://localhost:8081/auth/realms/demo/protocol/saml} + + ${sales-post-sig.url::http://localhost:8081/sales-post-sig/} + + + + + + + + + - - - - - - - - + + + + + + + + + diff --git a/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml b/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml index 2fb11caca1..1d170ee3a1 100755 --- a/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml +++ b/testsuite/integration/src/test/resources/saml/simple-get/WEB-INF/picketlink.xml @@ -10,7 +10,8 @@ class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" /> - + + diff --git a/testsuite/integration/src/test/resources/saml/simple-post/WEB-INF/picketlink.xml b/testsuite/integration/src/test/resources/saml/simple-post/WEB-INF/picketlink.xml index 4e20d7e401..73dab62719 100755 --- a/testsuite/integration/src/test/resources/saml/simple-post/WEB-INF/picketlink.xml +++ b/testsuite/integration/src/test/resources/saml/simple-post/WEB-INF/picketlink.xml @@ -12,8 +12,10 @@ class="org.picketlink.identity.federation.web.handlers.saml2.SAML2IssuerTrustHandler" /> - + + diff --git a/testsuite/integration/src/test/resources/saml/testsaml.json b/testsuite/integration/src/test/resources/saml/testsaml.json index 8098d5b0bb..4453c34fa0 100755 --- a/testsuite/integration/src/test/resources/saml/testsaml.json +++ b/testsuite/integration/src/test/resources/saml/testsaml.json @@ -61,6 +61,63 @@ "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw==" } }, + { + "name": "http://localhost:8081/sales-post-sig-transient/", + "enabled": true, + "protocol": "saml", + "fullScopeAllowed": true, + "baseUrl": "http://localhost:8081/sales-post-sig-transient", + "adminUrl": "http://localhost:8081/sales-post-sig-transient", + "redirectUris": [ + "http://localhost:8081/sales-post-sig-transient/*" + ], + "attributes": { + "saml.server.signature": "true", + "saml.signature.algorithm": "RSA_SHA256", + "saml.client.signature": "true", + "saml.authnstatement": "true", + "saml.signing.private.key": "MIICWwIBAAKBgQDVG8a7xGN6ZIkDbeecySygcDfsypjUMNPE4QJjis8B316CvsZQ0hcTTLUyiRpHlHZys2k3xEhHBHymFC1AONcvzZzpb40tAhLHO1qtAnut00khjAdjR3muLVdGkM/zMC7G5s9iIwBVhwOQhy+VsGnCH91EzkjZ4SVEr55KJoyQJQIDAQABAoGADaTtoG/+foOZUiLjRWKL/OmyavK9vjgyFtThNkZY4qHOh0h3og0RdSbgIxAsIpEa1FUwU2W5yvI6mNeJ3ibFgCgcxqPk6GkAC7DWfQfdQ8cS+dCuaFTs8ObIQEvU50YzeNPiiFxRA+MnauCUXaKm/PnDfjd4tPgru7XZvlGh0wECQQDsBbN2cKkBKpr/b5oJiBcBaSZtWiMNuYBDn9x8uORj+Gy/49BUIMHF2EWyxOWz6ocP5YiynNRkPe21Zus7PEr1AkEA5yWQOkxUTIg43s4pxNSeHtL+Ebqcg54lY2xOQK0yufxUVZI8ODctAKmVBMiCKpU3mZQquOaQicuGtocpgxlScQI/YM31zZ5nsxLGf/5GL6KhzPJT0IYn2nk7IoFu7bjn9BjwgcPurpLA52TNMYWQsTqAKwT6DEhG1NaRqNWNpb4VAkBehObAYBwMm5udyHIeEc+CzUalm0iLLa0eRdiN7AUVNpCJ2V2Uo0NcxPux1AgeP5xXydXafDXYkwhINWcNO9qRAkEA58ckAC5loUGwU5dLaugsGH/a2Q8Ac8bmPglwfCstYDpl8Gp/eimb1eKyvDEELOhyImAv4/uZV9wN85V0xZXWsw==", + "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw==" + } + }, + { + "name": "http://localhost:8081/sales-post-sig-persistent/", + "enabled": true, + "protocol": "saml", + "fullScopeAllowed": true, + "baseUrl": "http://localhost:8081/sales-post-sig-persistent", + "adminUrl": "http://localhost:8081/sales-post-sig-persistent", + "redirectUris": [ + "http://localhost:8081/sales-post-sig-persistent/*" + ], + "attributes": { + "saml.server.signature": "true", + "saml.signature.algorithm": "RSA_SHA256", + "saml.client.signature": "true", + "saml.authnstatement": "true", + "saml.signing.private.key": "MIICWwIBAAKBgQDVG8a7xGN6ZIkDbeecySygcDfsypjUMNPE4QJjis8B316CvsZQ0hcTTLUyiRpHlHZys2k3xEhHBHymFC1AONcvzZzpb40tAhLHO1qtAnut00khjAdjR3muLVdGkM/zMC7G5s9iIwBVhwOQhy+VsGnCH91EzkjZ4SVEr55KJoyQJQIDAQABAoGADaTtoG/+foOZUiLjRWKL/OmyavK9vjgyFtThNkZY4qHOh0h3og0RdSbgIxAsIpEa1FUwU2W5yvI6mNeJ3ibFgCgcxqPk6GkAC7DWfQfdQ8cS+dCuaFTs8ObIQEvU50YzeNPiiFxRA+MnauCUXaKm/PnDfjd4tPgru7XZvlGh0wECQQDsBbN2cKkBKpr/b5oJiBcBaSZtWiMNuYBDn9x8uORj+Gy/49BUIMHF2EWyxOWz6ocP5YiynNRkPe21Zus7PEr1AkEA5yWQOkxUTIg43s4pxNSeHtL+Ebqcg54lY2xOQK0yufxUVZI8ODctAKmVBMiCKpU3mZQquOaQicuGtocpgxlScQI/YM31zZ5nsxLGf/5GL6KhzPJT0IYn2nk7IoFu7bjn9BjwgcPurpLA52TNMYWQsTqAKwT6DEhG1NaRqNWNpb4VAkBehObAYBwMm5udyHIeEc+CzUalm0iLLa0eRdiN7AUVNpCJ2V2Uo0NcxPux1AgeP5xXydXafDXYkwhINWcNO9qRAkEA58ckAC5loUGwU5dLaugsGH/a2Q8Ac8bmPglwfCstYDpl8Gp/eimb1eKyvDEELOhyImAv4/uZV9wN85V0xZXWsw==", + "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw==" + } + }, + { + "name": "http://localhost:8081/sales-post-sig-email/", + "enabled": true, + "protocol": "saml", + "fullScopeAllowed": true, + "baseUrl": "http://localhost:8081/sales-post-sig-email", + "adminUrl": "http://localhost:8081/sales-post-sig-email", + "redirectUris": [ + "http://localhost:8081/sales-post-sig-email/*" + ], + "attributes": { + "saml.server.signature": "true", + "saml.signature.algorithm": "RSA_SHA256", + "saml.client.signature": "true", + "saml.authnstatement": "true", + "saml.signing.private.key": "MIICWwIBAAKBgQDVG8a7xGN6ZIkDbeecySygcDfsypjUMNPE4QJjis8B316CvsZQ0hcTTLUyiRpHlHZys2k3xEhHBHymFC1AONcvzZzpb40tAhLHO1qtAnut00khjAdjR3muLVdGkM/zMC7G5s9iIwBVhwOQhy+VsGnCH91EzkjZ4SVEr55KJoyQJQIDAQABAoGADaTtoG/+foOZUiLjRWKL/OmyavK9vjgyFtThNkZY4qHOh0h3og0RdSbgIxAsIpEa1FUwU2W5yvI6mNeJ3ibFgCgcxqPk6GkAC7DWfQfdQ8cS+dCuaFTs8ObIQEvU50YzeNPiiFxRA+MnauCUXaKm/PnDfjd4tPgru7XZvlGh0wECQQDsBbN2cKkBKpr/b5oJiBcBaSZtWiMNuYBDn9x8uORj+Gy/49BUIMHF2EWyxOWz6ocP5YiynNRkPe21Zus7PEr1AkEA5yWQOkxUTIg43s4pxNSeHtL+Ebqcg54lY2xOQK0yufxUVZI8ODctAKmVBMiCKpU3mZQquOaQicuGtocpgxlScQI/YM31zZ5nsxLGf/5GL6KhzPJT0IYn2nk7IoFu7bjn9BjwgcPurpLA52TNMYWQsTqAKwT6DEhG1NaRqNWNpb4VAkBehObAYBwMm5udyHIeEc+CzUalm0iLLa0eRdiN7AUVNpCJ2V2Uo0NcxPux1AgeP5xXydXafDXYkwhINWcNO9qRAkEA58ckAC5loUGwU5dLaugsGH/a2Q8Ac8bmPglwfCstYDpl8Gp/eimb1eKyvDEELOhyImAv4/uZV9wN85V0xZXWsw==", + "saml.signing.certificate": "MIIB1DCCAT0CBgFJGP5dZDANBgkqhkiG9w0BAQsFADAwMS4wLAYDVQQDEyVodHRwOi8vbG9jYWxob3N0OjgwODAvc2FsZXMtcG9zdC1zaWcvMB4XDTE0MTAxNjEyNDQyM1oXDTI0MTAxNjEyNDYwM1owMDEuMCwGA1UEAxMlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qtc2lnLzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1RvGu8RjemSJA23nnMksoHA37MqY1DDTxOECY4rPAd9egr7GUNIXE0y1MokaR5R2crNpN8RIRwR8phQtQDjXL82c6W+NLQISxztarQJ7rdNJIYwHY0d5ri1XRpDP8zAuxubPYiMAVYcDkIcvlbBpwh/dRM5I2eElRK+eSiaMkCUCAwEAATANBgkqhkiG9w0BAQsFAAOBgQCLms6htnPaY69k1ntm9a5jgwSn/K61cdai8R8B0ccY7zvinn9AfRD7fiROQpFyY29wKn8WCLrJ86NBXfgFUGyR5nLNHVy3FghE36N2oHy53uichieMxffE6vhkKJ4P8ChfJMMOZlmCPsQPDvjoAghHt4mriFiQgRdPgIy/zDjSNw==" + } + }, { "name": "http://localhost:8081/bad-realm-sales-post-sig/", "enabled": true,