From 28608a00d166efdc5806c7822d50fc345e924449 Mon Sep 17 00:00:00 2001
From: Tal Aharoni <105210819+talaharoni@users.noreply.github.com>
Date: Thu, 27 Jun 2024 21:45:15 +0300
Subject: [PATCH] Add sign key and encryption key configuration to SAML SSO
settings (#121)
* Add sign key and encryption key configuration to SAML SSO settings
* fix style
* fix style 2
* fix style 3 and last
---
examples/management-cli/pom.xml | 2 +-
pom.xml | 2 +-
.../descope/model/sso/SSOSAMLSettings.java | 3 ++
.../model/sso/SSOSAMLSettingsByMetadata.java | 3 ++
.../model/sso/SSOSAMLSettingsResponse.java | 2 ++
src/test/java/com/descope/sdk/TestUtils.java | 14 +++++++-
.../sdk/mgmt/impl/SsoServiceImplTest.java | 34 +++++++++++++++++++
7 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/examples/management-cli/pom.xml b/examples/management-cli/pom.xml
index ca63f8f9..88419f88 100644
--- a/examples/management-cli/pom.xml
+++ b/examples/management-cli/pom.xml
@@ -19,7 +19,7 @@
com.descope
java-sdk
- 1.0.25
+ 1.0.26
info.picocli
diff --git a/pom.xml b/pom.xml
index 92cf6568..469f8a1a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.descope
java-sdk
4.0.0
- 1.0.25
+ 1.0.26
${project.groupId}:${project.artifactId}
Java library used to integrate with Descope.
https://github.com/descope/descope-java
diff --git a/src/main/java/com/descope/model/sso/SSOSAMLSettings.java b/src/main/java/com/descope/model/sso/SSOSAMLSettings.java
index 8538e358..1864a0e8 100644
--- a/src/main/java/com/descope/model/sso/SSOSAMLSettings.java
+++ b/src/main/java/com/descope/model/sso/SSOSAMLSettings.java
@@ -16,4 +16,7 @@ public class SSOSAMLSettings {
private String idpCert;
private AttributeMapping attributeMapping;
private List roleMappings;
+ private String spEncryptionKey;
+ private String spSignKey;
+ private String subjectNameIdFormat;
}
diff --git a/src/main/java/com/descope/model/sso/SSOSAMLSettingsByMetadata.java b/src/main/java/com/descope/model/sso/SSOSAMLSettingsByMetadata.java
index d643c170..76e42e58 100644
--- a/src/main/java/com/descope/model/sso/SSOSAMLSettingsByMetadata.java
+++ b/src/main/java/com/descope/model/sso/SSOSAMLSettingsByMetadata.java
@@ -14,4 +14,7 @@ public class SSOSAMLSettingsByMetadata {
private String idpMetadataUrl;
private AttributeMapping attributeMapping;
private List roleMappings;
+ private String spEncryptionKey;
+ private String spSignKey;
+ private String subjectNameIdFormat;
}
diff --git a/src/main/java/com/descope/model/sso/SSOSAMLSettingsResponse.java b/src/main/java/com/descope/model/sso/SSOSAMLSettingsResponse.java
index 745d14b8..ae9119fb 100644
--- a/src/main/java/com/descope/model/sso/SSOSAMLSettingsResponse.java
+++ b/src/main/java/com/descope/model/sso/SSOSAMLSettingsResponse.java
@@ -21,4 +21,6 @@ public class SSOSAMLSettingsResponse {
private AttributeMapping attributeMapping;
private List groupsMapping;
private String redirectUrl;
+ private String spSignCertificate;
+ private String subjectNameIdFormat;
}
diff --git a/src/test/java/com/descope/sdk/TestUtils.java b/src/test/java/com/descope/sdk/TestUtils.java
index 1f16a61d..1b3019be 100644
--- a/src/test/java/com/descope/sdk/TestUtils.java
+++ b/src/test/java/com/descope/sdk/TestUtils.java
@@ -81,7 +81,19 @@ public class TestUtils {
.n(
"w8b3KRCep717H4MdVbwYHeb0vr891Ok1BL_TmC0XFUIKjRoKsWOcUZ9BFd6wR_5mnJuE7M8ZjVQRCbRlVgnh6AsEL3JA9Z6c1TpURTIXZxSE6NbeB7IMLMn5HWW7cjbnG4WO7E1PUCT6zCcBVz6EhA925GIJpyUxuY7oqJG-6NoOltI0Ocm6M2_7OIFMzFdw42RslqyX6l-SDdo_ZLq-XtcsCVRyj2YvmXUNF4Vq1x5syPOEQ-SezkvpBcb5Szi0ULpW5CvX2ieHAeHeQ2x8gkv6Dn2AW_dllQ--ZO-QH2QkxEXlMVqilwAdbA0k6BBtSkMC-7kD3A86bGGplpzz5Q")
.build();
-
+ public static final String MOCK_PRIVATE_KEY_STRING = "-----BEGIN PRIVATE KEY-----\n"
+ + "MIIB1QIBADANBgkqhkiG9w0BAQEFAASCAb8wggG7AgEAAl0DH3YqFv4mzt67RAAm\n"
+ + "KqZSY32GtoUqkLXzSJOIew2ofiKx3ojdJvL69pXZLKNoKkKb8RQKyWdhAIkbTEFX\n"
+ + "3k8mroXea5NMfB9NAH0AASQ6uoK5XYs7mMubQgu1dhcCAwEAAQJdAjrb+LAUaQe8\n"
+ + "+cFTze0UeK48Ow5nxn4wvniriIA9v3vaMGJ0Hl6qkFO1qq76O+uvSehxPHnzBrfs\n"
+ + "SXkQ8nScyeGpoTpn0DCnMnFRiY1hAMy6SqVdC4t7UP9u6oCBAi8B+POU6nCyUOnL\n"
+ + "FlPVGFoBxSoxC7q7tJytq+xaPfGBN63AT3sdnXm06YAH1uE/1wIvAZVPf+1sDjIP\n"
+ + "c4hFNPzIPh/x1M3qDN9eBr6tdPwymuPmpQ1lik/b9ZpMfXGns8ECLwDTVfcci+BF\n"
+ + "tyP1i06jq4AUKg1u8E+BTxXs37YBOOOxDvpvCYMiln6eP6SITavvAi8A6n71d8rl\n"
+ + "p6by4+uOjZXZA6hpw7zfN7hx1I4MugEZRjPiWI7f5/ZN8bjBdylcwQIvAQp1f9vQ\n"
+ + "S+P5ktRlO7vEm10LtKotJ85Rp+le7PX56re+nntKVZFsliKW0yPmWJE=\n"
+ + "-----END PRIVATE KEY-----";
+
private static SdkInfo getSdkInfo() {
String name = "java";
String version = System.getProperty("java.version");
diff --git a/src/test/java/com/descope/sdk/mgmt/impl/SsoServiceImplTest.java b/src/test/java/com/descope/sdk/mgmt/impl/SsoServiceImplTest.java
index 3fd8ec56..95cd6e81 100644
--- a/src/test/java/com/descope/sdk/mgmt/impl/SsoServiceImplTest.java
+++ b/src/test/java/com/descope/sdk/mgmt/impl/SsoServiceImplTest.java
@@ -273,6 +273,13 @@ void testFunctionalFullCycleSAML() {
String name = TestUtils.getRandomName("t-");
String tenantId = tenantService.create(name, Arrays.asList(name + ".com", name + "1.com"));
assertThat(tenantId).isNotBlank();
+ SSOTenantSettingsResponse beforeUpdateResp = ssoService.loadSettings(tenantId);
+ assertEquals(tenantId, beforeUpdateResp.getTenant().getId());
+ String encryptCert = beforeUpdateResp.getSaml().getSpCertificate();
+ assertThat(encryptCert).isNotBlank();
+ String signCert = beforeUpdateResp.getSaml().getSpSignCertificate();
+ assertThat(signCert).isNotBlank();
+ final String unspecifiedFormat = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified";
ssoService.configureSAMLSettings(tenantId, SSOSAMLSettings.builder()
.attributeMapping(AttributeMapping.builder()
.email("email")
@@ -281,6 +288,9 @@ void testFunctionalFullCycleSAML() {
.entityId("entityId")
.idpCert("idpCert")
.idpUrl("https://" + name + ".com")
+ .spEncryptionKey(TestUtils.MOCK_PRIVATE_KEY_STRING)
+ .spSignKey(TestUtils.MOCK_PRIVATE_KEY_STRING)
+ .subjectNameIdFormat(unspecifiedFormat)
.build(), "https://" + name + ".com", null);
SSOTenantSettingsResponse resp = ssoService.loadSettings(tenantId);
assertEquals(tenantId, resp.getTenant().getId());
@@ -290,6 +300,13 @@ void testFunctionalFullCycleSAML() {
assertEquals("idpCert", resp.getSaml().getIdpCertificate());
assertEquals("https://" + name + ".com", resp.getSaml().getIdpSSOUrl());
assertEquals("https://" + name + ".com", resp.getSaml().getRedirectUrl());
+ String newEncryptCert = resp.getSaml().getSpCertificate();
+ assertThat(newEncryptCert).isNotBlank();
+ assertThat(newEncryptCert).isNotEqualTo(encryptCert);
+ String newSignCert = resp.getSaml().getSpSignCertificate();
+ assertThat(signCert).isNotBlank();
+ assertThat(newSignCert).isNotEqualTo(signCert);
+ assertThat(unspecifiedFormat).isEqualTo(resp.getSaml().getSubjectNameIdFormat());
ssoService.deleteSettings(tenantId);
tenantService.delete(tenantId);
}
@@ -299,8 +316,15 @@ void testFunctionalFullCycleSAMLMetadata() {
String name = TestUtils.getRandomName("t-");
String tenantId = tenantService.create(name, Arrays.asList(name + ".com", name + "1.com"));
assertThat(tenantId).isNotBlank();
+ SSOTenantSettingsResponse beforeUpdateResp = ssoService.loadSettings(tenantId);
+ assertEquals(tenantId, beforeUpdateResp.getTenant().getId());
+ String encryptCert = beforeUpdateResp.getSaml().getSpCertificate();
+ assertThat(encryptCert).isNotBlank();
+ String signCert = beforeUpdateResp.getSaml().getSpSignCertificate();
+ assertThat(signCert).isNotBlank();
String roleName = TestUtils.getRandomName("rt-").substring(0, 20);
rolesService.create(roleName, tenantId, "ttt", null);
+ final String unspecifiedFormat = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified";
ssoService.configureSAMLSettingsByMetadata(tenantId, SSOSAMLSettingsByMetadata.builder()
.attributeMapping(AttributeMapping.builder()
.email("email")
@@ -308,6 +332,9 @@ void testFunctionalFullCycleSAMLMetadata() {
.build())
.idpMetadataUrl("https://" + name + ".com/md")
.roleMappings(Arrays.asList(RoleMapping.builder().groups(Arrays.asList("a", "b")).roleName(roleName).build()))
+ .spEncryptionKey(TestUtils.MOCK_PRIVATE_KEY_STRING)
+ .spSignKey(TestUtils.MOCK_PRIVATE_KEY_STRING)
+ .subjectNameIdFormat(unspecifiedFormat)
.build(), "https://" + name + ".com", null);
SSOTenantSettingsResponse resp = ssoService.loadSettings(tenantId);
assertEquals(tenantId, resp.getTenant().getId());
@@ -318,6 +345,13 @@ void testFunctionalFullCycleSAMLMetadata() {
assertNotNull(groupsMapping);
assertThat(groupsMapping).hasSize(1);
assertThat(groupsMapping.get(0).getRole().getId()).isNotBlank();
+ String newEncryptCert = resp.getSaml().getSpCertificate();
+ assertThat(newEncryptCert).isNotBlank();
+ assertThat(newEncryptCert).isNotEqualTo(encryptCert);
+ String newSignCert = resp.getSaml().getSpSignCertificate();
+ assertThat(signCert).isNotBlank();
+ assertThat(newSignCert).isNotEqualTo(signCert);
+ assertThat(unspecifiedFormat).isEqualTo(resp.getSaml().getSubjectNameIdFormat());
ssoService.deleteSettings(tenantId);
tenantService.delete(tenantId);
}