diff --git a/pom.xml b/pom.xml
index f0c12e2914..964b9266ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -80,7 +80,7 @@
0.10.5
1.2.3
4.5.13
- 3.4.4
+ 3.4.5
2.5.0
2.5.0
3.4.5
diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java
index b36972a531..9613a2ade1 100644
--- a/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java
+++ b/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java
@@ -22,6 +22,7 @@
import java.util.Map.Entry;
import java.util.regex.Pattern;
+import com.google.common.annotations.VisibleForTesting;
import org.apache.cxf.rs.security.jose.jwt.JwtClaims;
import org.apache.cxf.rs.security.jose.jwt.JwtToken;
import org.apache.http.HttpHeaders;
@@ -163,7 +164,8 @@ protected String getJwtTokenString(RestRequest request) {
return jwtToken;
}
- protected String extractSubject(JwtClaims claims) {
+ @VisibleForTesting
+ public String extractSubject(JwtClaims claims) {
String subject = claims.getSubject();
if (subjectKey != null) {
@@ -189,7 +191,8 @@ protected String extractSubject(JwtClaims claims) {
}
@SuppressWarnings("unchecked")
- protected String[] extractRoles(JwtClaims claims) {
+ @VisibleForTesting
+ public String[] extractRoles(JwtClaims claims) {
if (rolesKey == null) {
return new String[0];
}
diff --git a/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java
index 96beff9051..5d73f24c7a 100644
--- a/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java
+++ b/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java
@@ -22,6 +22,7 @@
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import com.google.common.annotations.VisibleForTesting;
import net.shibboleth.utilities.java.support.xml.BasicParserPool;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
@@ -95,7 +96,8 @@ public class HTTPSamlAuthenticator implements HTTPAuthenticator, Destroyable {
private Saml2SettingsProvider saml2SettingsProvider;
private MetadataResolver metadataResolver;
private AuthTokenProcessorHandler authTokenProcessorHandler;
- private HTTPJwtAuthenticator httpJwtAuthenticator;
+ @VisibleForTesting
+ protected HTTPJwtAuthenticator httpJwtAuthenticator;
private Settings jwtSettings;
private static int resolverIdCounter = 0;
diff --git a/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java b/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java
index d8efce92db..0ae0e4824a 100644
--- a/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java
+++ b/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java
@@ -193,6 +193,90 @@ public void decryptAssertionsTest() throws Exception {
Assert.assertEquals("horst", jwt.getClaim("sub"));
}
+ @Test
+ public void unescapeSamlEntitiesTest() throws Exception {
+ mockSamlIdpServer.setAuthenticateUser("ABC\\User1");
+ mockSamlIdpServer.setEndpointQueryString(null);
+ mockSamlIdpServer.setSpSignatureCertificate(spSigningCertificate);
+ mockSamlIdpServer.setEncryptAssertion(true);
+ mockSamlIdpServer.setAuthenticateUserRoles(Arrays.asList("ABC\\Admin"));
+
+ Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri())
+ .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId())
+ .put("sp.signature_private_key", "-BEGIN PRIVATE KEY-\n"
+ + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-")
+ .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build();
+
+ HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null);
+
+ AuthenticateHeaders authenticateHeaders = getAutenticateHeaders(samlAuthenticator);
+
+ String encodedSamlResponse = mockSamlIdpServer.handleSsoGetRequestURI(authenticateHeaders.location);
+
+ RestRequest tokenRestRequest = buildTokenExchangeRestRequest(encodedSamlResponse, authenticateHeaders);
+ TestRestChannel tokenRestChannel = new TestRestChannel(tokenRestRequest);
+
+ samlAuthenticator.reRequestAuthentication(tokenRestChannel, null);
+
+ String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content()));
+ HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson,
+ new TypeReference>() {
+ });
+ String authorization = (String) response.get("authorization");
+
+ Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization);
+
+ JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(authorization.replaceAll("\\s*bearer\\s*", ""));
+ JwtToken jwt = jwtConsumer.getJwtToken();
+
+ Assert.assertEquals("ABC\\User1", jwt.getClaim("sub"));
+ Assert.assertEquals("ABC\\User1", samlAuthenticator.httpJwtAuthenticator.extractSubject(jwt.getClaims()));
+ Assert.assertEquals("[ABC\\Admin]", String.valueOf(jwt.getClaim("roles")));
+ Assert.assertEquals("ABC\\Admin", samlAuthenticator.httpJwtAuthenticator.extractRoles(jwt.getClaims())[0]);
+ }
+
+ @Test
+ public void unescapeSamlEntitiesTest2() throws Exception {
+ mockSamlIdpServer.setAuthenticateUser("ABC\"User1");
+ mockSamlIdpServer.setEndpointQueryString(null);
+ mockSamlIdpServer.setSpSignatureCertificate(spSigningCertificate);
+ mockSamlIdpServer.setEncryptAssertion(true);
+ mockSamlIdpServer.setAuthenticateUserRoles(Arrays.asList("ABC\"Admin"));
+
+ Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri())
+ .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId())
+ .put("sp.signature_private_key", "-BEGIN PRIVATE KEY-\n"
+ + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-")
+ .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build();
+
+ HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null);
+
+ AuthenticateHeaders authenticateHeaders = getAutenticateHeaders(samlAuthenticator);
+
+ String encodedSamlResponse = mockSamlIdpServer.handleSsoGetRequestURI(authenticateHeaders.location);
+
+ RestRequest tokenRestRequest = buildTokenExchangeRestRequest(encodedSamlResponse, authenticateHeaders);
+ TestRestChannel tokenRestChannel = new TestRestChannel(tokenRestRequest);
+
+ samlAuthenticator.reRequestAuthentication(tokenRestChannel, null);
+
+ String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content()));
+ HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson,
+ new TypeReference>() {
+ });
+ String authorization = (String) response.get("authorization");
+
+ Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization);
+
+ JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(authorization.replaceAll("\\s*bearer\\s*", ""));
+ JwtToken jwt = jwtConsumer.getJwtToken();
+
+ Assert.assertEquals("ABC\"User1", jwt.getClaim("sub"));
+ Assert.assertEquals("ABC\"User1", samlAuthenticator.httpJwtAuthenticator.extractSubject(jwt.getClaims()));
+ Assert.assertEquals("[ABC\"Admin]", String.valueOf(jwt.getClaim("roles")));
+ Assert.assertEquals("ABC\"Admin", samlAuthenticator.httpJwtAuthenticator.extractRoles(jwt.getClaims())[0]);
+ }
+
@Test
public void testMetadataBody() throws Exception {
mockSamlIdpServer.setSignResponses(true);