Repository: SAP/cloud-security-xsuaa-integration
Pull request #709 (2021-11-09 10:04:41)

Bump dependency-check-maven from 6.4.1 to 6.5.0
Bumps [dependency-check-maven](https://github.com/jeremylong/DependencyCheck) from 6.4.1 to 6.5.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/jeremylong/DependencyCheck/releases">dependency-check-maven's releases</a>.</em></p>
<blockquote>
<h2>Version 6.5.0</h2>
<p>Changes in this Release</p>
<ul>
<li>Updated build configuration to create <a href="https://reproducible-builds.org/">reproducible builds</a>.</li>
<li>Updated automated release process to work with branch protection.</li>
<li>Resolved several false positives in the Java ecosystem.</li>
<li>Enabled the Swift Resolved analyzer per <a href="https://github-redirect.dependabot.com/jeremylong/DependencyCheck/issues/3735">#3735</a></li>
<li>Improved iOS support per <a href="https://github-redirect.dependabot.com/jeremylong/DependencyCheck/issues/3168">#3168</a> and <a href="https://github-redirect.dependabot.com/jeremylong/DependencyCheck/issues/3765">#3765</a></li>
<li>Added the a new pnpm Analyzer</li>
<li>Fixed issue with some npm and yarn analysis failing due to large audit output</li>
<li>See the full listing of <a href="https://github.com/jeremylong/DependencyCheck/milestone/36?closed=1">changes</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/jeremylong/DependencyCheck/blob/main/RELEASE_NOTES.md">dependency-check-maven's changelog</a>.</em></p>
<blockquote>
<h2><a href="https://github.com/jeremylong/DependencyCheck/releases/tag/v6.5.0">Version 6.5.0</a> (2021-11-08)</h2>
<h3>Changes</h3>
<ul>
<li>Updated build configuration to create <a href="https://reproducible-builds.org/">reproducible builds</a>.</li>
<li>Updated automated release process to work with branch protection.</li>
<li>Resolved several false positives in the Java ecosystem.</li>
<li>Enabled the Swift Resolved analyzer per <a href="https://github-redirect.dependabot.com/jeremylong/DependencyCheck/issues/3735">#3735</a></li>
<li>Improved iOS support per <a href="https://github-redirect.dependabot.com/jeremylong/DependencyCheck/issues/3168">#3168</a> and <a href="https://github-redirect.dependabot.com/jeremylong/DependencyCheck/issues/3765">#3765</a></li>
<li>Added the a new pnpm Analyzer</li>
<li>Fixed issue with some npm and yarn analysis failing due to large audit output</li>
<li>See the full listing of <a href="https://github.com/jeremylong/DependencyCheck/milestone/36?closed=1">changes</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/jeremylong/DependencyCheck/commit/47737f09ae1ee69b18196c0744c247b789b3521c"><code>47737f0</code></a> [maven-release-plugin] prepare release v6.5.0</li>
<li><a href="https://github.com/jeremylong/DependencyCheck/commit/0e10d48b64ee59892443540448225e317e7e5e1e"><code>0e10d48</code></a> 6.5.0 release notes</li>
<li><a href="https://github.com/jeremylong/DependencyCheck/commit/d60ab271112af616991572033d692bed07220148"><code>d60ab27</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/jeremylong/DependencyCheck/issues/3781">#3781</a> from jeremylong/updateReleaseWorkflow</li>
<li><a href="https://github.com/jeremylong/DependencyCheck/commit/d28073469f832dbf3193628322a3ffe0066a86fc"><code>d280734</code></a> updated based on codacy recommendation</li>
<li><a href="https://github.com/jeremylong/DependencyCheck/commit/0c35bb46c0c478f55140d7f36b7ccfed7edbca0a"><code>0c35bb4</code></a> update release workflow for protected branches</li>
<li><a href="https://github.com/jeremylong/DependencyCheck/commit/81990eae332afa9fbb1c5f550aad78fe4878af8c"><code>81990ea</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/jeremylong/DependencyCheck/issues/3780">#3780</a> from jeremylong/reproducible</li>
<li><a href="https://github.com/jeremylong/DependencyCheck/commit/24f58e97d2af1403e1f3fd3a6c53985bf4f74feb"><code>24f58e9</code></a> updates for Reproducible Builds</li>
<li><a href="https://github.com/jeremylong/DependencyCheck/commit/547e7a1c1e450e1c69d844b747f3f47a1ad35126"><code>547e7a1</code></a> fp per <a href="https://github-redirect.dependabot.com/jeremylong/DependencyCheck/issues/3778">#3778</a></li>
<li><a href="https://github.com/jeremylong/DependencyCheck/commit/0f941aeec08af1ce2c9855e97424940d62fd6576"><code>0f941ae</code></a> make checkstyle and spotbugs happier</li>
<li><a href="https://github.com/jeremylong/DependencyCheck/commit/167b20c0c1dacd29292b95a2d66736d7b38502f0"><code>167b20c</code></a> Merge branch 'main' of github.com:jeremylong/DependencyCheck into main</li>
<li>Additional commits viewable in <a href="https://github.com/jeremylong/DependencyCheck/compare/v6.4.1...v6.5.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.owasp:dependency-check-maven&package-manager=maven&previous-version=6.4.1&new-version=6.5.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/java-api/pom.xml b/java-api/pom.xml
index 3a7ef4f6..7998e7d6 100644
--- a/java-api/pom.xml
+++ b/java-api/pom.xml
@@ -69,11 +69,6 @@
 			<artifactId>commons-io</artifactId>
 			<scope>test</scope>
 		</dependency>
-		<dependency> <!-- check if it's still needed when slf4j-api 1.8 is available -->
-			<groupId>org.slf4j</groupId>
-			<artifactId>slf4j-simple</artifactId>
-			<scope>test</scope>
-		</dependency>
 	</dependencies>
 
 	<build>
diff --git a/java-api/src/main/java/com/sap/cloud/security/token/Token.java b/java-api/src/main/java/com/sap/cloud/security/token/Token.java
index 4afd8a5f..db062d54 100644
--- a/java-api/src/main/java/com/sap/cloud/security/token/Token.java
+++ b/java-api/src/main/java/com/sap/cloud/security/token/Token.java
@@ -14,12 +14,11 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import java.io.Serializable;
 import java.security.Principal;
+import java.security.ProviderException;
 import java.time.Instant;
 import java.util.*;
 
-import static com.sap.cloud.security.token.TokenClaims.AUDIENCE;
-import static com.sap.cloud.security.token.TokenClaims.AUTHORIZATION_PARTY;
-import static com.sap.cloud.security.token.TokenClaims.ISSUER;
+import static com.sap.cloud.security.token.TokenClaims.*;
 
 /**
  * Represents a JSON Web Token (JWT).
@@ -34,6 +33,8 @@ public interface Token extends Serializable {
 		}
 	};
 
+	String DEFAULT_TOKEN_FACTORY = "com.sap.cloud.security.servlet.HybridTokenFactory";
+
 	/**
 	 * Creates a token instance based on TokenFactory implementation.
 	 * 
@@ -45,6 +46,15 @@ public interface Token extends Serializable {
 		if (services.isEmpty()) {
 			throw new ProviderNotFoundException("No TokenFactory implementation found in the classpath");
 		}
+		if (services.size() > 2) {
+			throw new ProviderException("More than 1 Custom TokenFactory service provider found. There should be only one");
+		}
+		if (services.size() == 2) {
+			return services.stream()
+					.filter(tokenFactory -> !tokenFactory.getClass().getName()
+							.equals(DEFAULT_TOKEN_FACTORY))
+					.findFirst().get().create(jwt);
+		}
 		return services.get(0).create(jwt);
 	}
 
diff --git a/pom.xml b/pom.xml
index 7c59f5d6..a5bec274 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,7 +63,7 @@
 		<spring.security.version>5.5.3</spring.security.version>
 		<spring.security.oauth2.version>2.5.1.RELEASE</spring.security.oauth2.version>
 		<spring.security.jwt.version>1.1.1.RELEASE</spring.security.jwt.version>
-		<reactor.version>3.4.11</reactor.version>
+		<reactor.version>3.4.12</reactor.version>
 		<log4j.version>2.14.1</log4j.version>
 		<slf4j.api.version>1.7.32</slf4j.api.version> <!--see also here http://www.slf4j.org/faq.html#changesInVersion18 -->
 		<org.json.version>20210307</org.json.version>
@@ -79,7 +79,7 @@
 		<hamcrest.version>1.3</hamcrest.version>
 		<mockito.version>3.12.4</mockito.version>
 		<assertj.version>3.21.0</assertj.version>
-		<reactor.test.version>3.4.11</reactor.test.version>
+		<reactor.test.version>3.4.12</reactor.test.version>
 		<wiremock.version>2.31.0</wiremock.version>
 		<skipTests>false</skipTests>
 		<jacoco.skip>${skipTests}</jacoco.skip>
@@ -391,7 +391,7 @@
 						<plugin>
 							<groupId>org.owasp</groupId> <!--scans for vulnerabilities-->
 							<artifactId>dependency-check-maven</artifactId>
-							<version>6.4.1</version>
+							<version>6.5.0</version>
 							<executions>
 								<execution>
 									<goals>
diff --git a/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/XsuaaServiceConfiguration.java b/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/XsuaaServiceConfiguration.java
index 9e31bf6d..5ed98540 100644
--- a/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/XsuaaServiceConfiguration.java
+++ b/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/XsuaaServiceConfiguration.java
@@ -5,6 +5,7 @@
  */
 package com.sap.cloud.security.xsuaa;
 
+import com.sap.cloud.security.config.ClientIdentity;
 import com.sap.cloud.security.config.OAuth2ServiceConfiguration;
 import com.sap.cloud.security.config.Service;
 
@@ -65,6 +66,14 @@ public interface XsuaaServiceConfiguration extends OAuth2ServiceConfiguration {
 		throw new UnsupportedOperationException("hasProperty method is not supported");
 	}
 
+	@Override
+	default ClientIdentity getClientIdentity() {
+		throw new UnsupportedOperationException(
+				"This default method needs to be overridden to be used! Default method from " +
+						"com.sap.cloud.security.config.OAuth2ServiceConfiguration#getClientIdentity() " +
+						"is not compatible with XsuaaServiceConfiguration interface");
+	}
+
 	@Override
 	default Service getService() {
 		throw new UnsupportedOperationException("getService method is not supported");
diff --git a/token-client/pom.xml b/token-client/pom.xml
index 0a9b8b28..211b4f43 100644
--- a/token-client/pom.xml
+++ b/token-client/pom.xml
@@ -97,11 +97,6 @@
 			<artifactId>spring-security-oauth2-jose</artifactId>
 			<scope>test</scope>
 		</dependency>
-		<dependency> <!-- check if it's still needed when slf4j-api 1.8 is available -->
-			<groupId>org.slf4j</groupId>
-			<artifactId>slf4j-simple</artifactId>
-			<scope>test</scope>
-		</dependency>
 	</dependencies>
 
 	<build>
diff --git a/token-client/src/main/java/com/sap/cloud/security/client/DefaultHttpClientFactory.java b/token-client/src/main/java/com/sap/cloud/security/client/DefaultHttpClientFactory.java
index 17b55f27..79bb944e 100644
--- a/token-client/src/main/java/com/sap/cloud/security/client/DefaultHttpClientFactory.java
+++ b/token-client/src/main/java/com/sap/cloud/security/client/DefaultHttpClientFactory.java
@@ -25,6 +25,7 @@ public class DefaultHttpClientFactory implements HttpClientFactory {
 
 	private static final Logger LOGGER = LoggerFactory.getLogger(DefaultHttpClientFactory.class);
 
+	@Override
 	public CloseableHttpClient createClient(ClientIdentity clientIdentity) throws HttpClientException {
 		LOGGER.warn("In productive environment provide well configured HttpClientFactory service");
 		if (clientIdentity != null && clientIdentity.isCertificateBased()) {
diff --git a/token-client/src/main/java/com/sap/cloud/security/client/HttpClientFactory.java b/token-client/src/main/java/com/sap/cloud/security/client/HttpClientFactory.java
index 57681c1e..f8d37a0b 100644
--- a/token-client/src/main/java/com/sap/cloud/security/client/HttpClientFactory.java
+++ b/token-client/src/main/java/com/sap/cloud/security/client/HttpClientFactory.java
@@ -11,6 +11,7 @@ import com.sap.cloud.security.token.ProviderNotFoundException;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.slf4j.LoggerFactory;
 
+import java.security.ProviderException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.ServiceLoader;
@@ -19,6 +20,7 @@ import java.util.ServiceLoader;
  * Represents a {@link CloseableHttpClient} creation interface.
  */
 public interface HttpClientFactory {
+
 	@SuppressWarnings("unchecked")
 	List<HttpClientFactory> services = new ArrayList() {
 		{
@@ -28,6 +30,9 @@ public interface HttpClientFactory {
 		}
 	};
 
+	String DEFAULT_HTTP_CLIENT_FACTORY = "com.sap.cloud.security.client.DefaultHttpClientFactory";
+
+
 	/**
 	 * Provides CloseableHttpClient based on ClientIdentity details. For
 	 * ClientIdentity that is certificate based it will resolve https client using
@@ -48,6 +53,16 @@ public interface HttpClientFactory {
 		if (services.isEmpty()) {
 			throw new ProviderNotFoundException("No HttpClientFactory service could be found in the classpath");
 		}
+		if (services.size() > 2) {
+			throw new ProviderException(
+					"More than 1 Custom HttpClientFactory service provider found. There should be only one");
+		}
+		if (services.size() == 2) {
+			return services.stream()
+					.filter(httpClientFactory -> !httpClientFactory.getClass().getName()
+							.equals(DEFAULT_HTTP_CLIENT_FACTORY))
+					.findFirst().get().createClient(clientIdentity);
+		}
 		return services.get(0).createClient(clientIdentity);
 	}
 


Test patch:
diff --git a/java-api/src/test/java/com/sap/cloud/security/servlet/HybridTokenFactory.java b/java-api/src/test/java/com/sap/cloud/security/servlet/HybridTokenFactory.java
new file mode 100644
index 00000000..b33357cf
--- /dev/null
+++ b/java-api/src/test/java/com/sap/cloud/security/servlet/HybridTokenFactory.java
@@ -0,0 +1,19 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ * <p>
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.servlet;
+
+import com.sap.cloud.security.token.AccessToken;
+import com.sap.cloud.security.token.Token;
+import com.sap.cloud.security.token.TokenFactory;
+import org.mockito.Mockito;
+
+public class HybridTokenFactory implements TokenFactory {
+
+	@Override
+	public Token create(String jwtToken) {
+		return Mockito.mock(AccessToken.class);
+	}
+}
diff --git a/java-api/src/test/java/com/sap/cloud/security/token/TokenTest.java b/java-api/src/test/java/com/sap/cloud/security/token/TokenTest.java
index 8aecb404..7265e60f 100644
--- a/java-api/src/test/java/com/sap/cloud/security/token/TokenTest.java
+++ b/java-api/src/test/java/com/sap/cloud/security/token/TokenTest.java
@@ -7,6 +7,7 @@ package com.sap.cloud.security.token;
 
 import org.junit.Test;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 
 public class TokenTest {
@@ -18,5 +19,10 @@ public class TokenTest {
 
 		cut = Token.create("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9");
 		assertNotNull(cut);
+
+		// Assert that custom Token factory has a priority over default
+		// com.sap.cloud.security.servlet.HybridTokenFactory
+		assertFalse(cut.getClass().getName().contains("AccessToken"));
 	}
+
 }
diff --git a/java-api/src/test/resources/META-INF/services/com.sap.cloud.security.token.TokenFactory b/java-api/src/test/resources/META-INF/services/com.sap.cloud.security.token.TokenFactory
index c2cb9383..70fc90c0 100644
--- a/java-api/src/test/resources/META-INF/services/com.sap.cloud.security.token.TokenFactory
+++ b/java-api/src/test/resources/META-INF/services/com.sap.cloud.security.token.TokenFactory
@@ -1,1 +1,2 @@
+com.sap.cloud.security.servlet.HybridTokenFactory
 com.sap.cloud.security.token.test.CustomTokenFactory
\ No newline at end of file
diff --git a/spring-xsuaa/src/test/java/com/sap/cloud/security/xsuaa/DummyXsuaaServiceConfiguration.java b/spring-xsuaa/src/test/java/com/sap/cloud/security/xsuaa/DummyXsuaaServiceConfiguration.java
index 6a33f4f6..8c9f8d3a 100644
--- a/spring-xsuaa/src/test/java/com/sap/cloud/security/xsuaa/DummyXsuaaServiceConfiguration.java
+++ b/spring-xsuaa/src/test/java/com/sap/cloud/security/xsuaa/DummyXsuaaServiceConfiguration.java
@@ -5,6 +5,8 @@
  */
 package com.sap.cloud.security.xsuaa;
 
+import com.sap.cloud.security.config.ClientCredentials;
+import com.sap.cloud.security.config.ClientIdentity;
 import com.sap.cloud.security.config.CredentialType;
 
 public class DummyXsuaaServiceConfiguration implements XsuaaServiceConfiguration {
@@ -56,9 +58,9 @@ public class DummyXsuaaServiceConfiguration implements XsuaaServiceConfiguration
 		return null;
 	}
 
-	// TODO remove once credential-type is available in IAS configuration
 	@Override
-	public String getProperty(String name) {
-		return null;
+	public ClientIdentity getClientIdentity() {
+		return new ClientCredentials(getClientId(), getClientSecret());
 	}
+
 }
diff --git a/token-client/src/test/java/com/sap/cloud/security/client/HttpClientFactoryTest.java b/token-client/src/test/java/com/sap/cloud/security/client/HttpClientFactoryTest.java
new file mode 100644
index 00000000..9313a1b6
--- /dev/null
+++ b/token-client/src/test/java/com/sap/cloud/security/client/HttpClientFactoryTest.java
@@ -0,0 +1,27 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ * <p>
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.client;
+
+import com.sap.cloud.security.config.ClientCredentials;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class HttpClientFactoryTest {
+
+	@Test
+	public void create() {
+		CloseableHttpClient cut = HttpClientFactory.create(new ClientCredentials("clientId", "secret"));
+		assertNotNull(cut);
+
+		// Assert that custom HttpClientFactory factory has a priority over default
+		// com.sap.cloud.security.client.DefaultHttpClientFactory
+		assertFalse(cut.getClass().getName().contains("InternalHttpClient"));
+		assertTrue(cut.getClass().getName().contains("CloseableHttpClient$MockitoMock"));
+	}
+
+}
\ No newline at end of file
diff --git a/token-client/src/test/java/com/sap/cloud/security/client/TestHttpClientFactory.java b/token-client/src/test/java/com/sap/cloud/security/client/TestHttpClientFactory.java
new file mode 100644
index 00000000..ee2d7f66
--- /dev/null
+++ b/token-client/src/test/java/com/sap/cloud/security/client/TestHttpClientFactory.java
@@ -0,0 +1,18 @@
+/**
+ * SPDX-FileCopyrightText: 2018-2021 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
+ * <p>
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.client;
+
+import com.sap.cloud.security.config.ClientIdentity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.mockito.Mockito;
+
+public class TestHttpClientFactory implements HttpClientFactory {
+
+	@Override
+	public CloseableHttpClient createClient(ClientIdentity clientIdentity) throws HttpClientException {
+		return Mockito.mock(CloseableHttpClient.class);
+	}
+}
diff --git a/token-client/src/test/resources/META-INF/services/com.sap.cloud.security.client.HttpClientFactory b/token-client/src/test/resources/META-INF/services/com.sap.cloud.security.client.HttpClientFactory
new file mode 100644
index 00000000..6b945a92
--- /dev/null
+++ b/token-client/src/test/resources/META-INF/services/com.sap.cloud.security.client.HttpClientFactory
@@ -0,0 +1,2 @@
+com.sap.cloud.security.client.DefaultHttpClientFactory
+com.sap.cloud.security.client.TestHttpClientFactory
\ No newline at end of file