Repository: SAP/cloud-security-xsuaa-integration
Pull request #320 (2020-06-30 13:27:49)

Log token content/jwt validator config on failed authentication
This is the simple solution for token logging more information on failed authentication attemps.

Todos:
- [x] AbstractToken.toString() provides token payload (maybe via DecodedJwt)
- [x] This should be logged in case validation fails.
- [x] Optional: log should provide validator that fails.
- [x] Optional: logging should be possible not only via Authenticator


hassler-d: Now I have implemented the TODOs described above in a simple way without breaking changes.
This is how it looks like on failed validations now:
```log
[main] WARN com.sap.cloud.security.token.validation.ValidationResults - Jwt expired at 2019-10-26T03:32:49Z, time now: 2020-07-01T13:06:00.099Z
[main] DEBUG com.sap.cloud.security.token.validation.CombiningValidator - Validator that caused the failed validation: com.sap.cloud.security.token.validation.validators.JwtTimestampValidator
[main] DEBUG com.sap.cloud.security.token.validation.validators.JwtValidatorBuilder - Token that caused the failed validation: 
Jwt header
	{"alg":"RS256","jku":"https://authentication.stagingaws.hanavlab.ondemand.com/token_keys","kid":"key-id-1","typ":"JWT"}
Jwt payload
	{"jti":"2a6b47182ce34c83a3c4641b556b946c","ext_attr":{"enhancer":"XSUAA"},"sub":"sap_osb","authorities":["uaa.resource","ROLE_SERVICEBROKER"],"scope":["ROLE_SERVICEBROKER","uaa.resource"],"client_id":"sap_osb","cid":"sap_osb","azp":"sap_osb","grant_type":"client_credentials","rev_sig":"b23a72dc","iat":1572017569,"exp":1572060769,"iss":"http://localhost:8080/uaa/oauth/token","zid":"uaa","aud":["uaa","sap_osb"]}
```
I avoided adding the `Token` to the `ValidationResult` class because it would result in a lot of changes in the existing code. 
Furthermore the `ValidationResult` is used in the `Validator<T>` interface which is generic. If we add the `Token` to the  `ValidationResult` this would mean that every `ValidationResult` now contains a `Token` which only applies to validators that validate tokens. But since `Validator<T>` is generic, the ValidationResult that it uses  should not contain specifics. That would feel very strange. There are two solutions to this: (1) Make `ValidationResult` also generic over `T`, e.g. `ValidationResult<T>` (2) Get rid of the generics for the validation! There are only ever used for validating tokens anyway. 
By now I would prefer (2) but it would be a big breaking change. Option (1) could be implemented without a breaking change but I suspect the API would look better if this would be implemented with a breaking change also...
That is why I did not change the `ValidationResult`. I think we could change this someday (probably major release?). But it should not be part of this PR!


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 74dded38..29109fed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
 
 All notable changes to this project will be documented in this file.
 
+## 2.7.5
+- [java-api] `AcessToken` provides `getAttributeFromClaimAsString(String claimName, String attributeName)` to access for example `ext_attr` values such as `subaccountid`...
+- [java-security] provide debug logs for failing token validation, see [troubleshoot](/java-security/Migration_SAPJavaBuildpackProjects.md).
+- [java-security-test] Fixed default value for jku token header to `http://localhost/token_keys`
+
 ## 2.7.4
 - [java-security] Audience Validation validates to true when the derived `client_id` of broker-clone token matches the trusted client. This is relevant to support tokens of grant type `user_token` that contains no scopes.
 
@@ -20,7 +25,7 @@ All notable changes to this project will be documented in this file.
   - In upcoming releases - especially for new subaccounts - subaccount id will no longer match the tenant GUID which is provided via the xsuaa access token as `zid` claim or via the ias oidc token as `zone_uuid` claim.
 
 ## 2.7.1
-- [java-security] 
+- [java-security] (SAP Java Buildpack version 1.26.1)
   - rename Token claim "sap_uid" to „user_uuid“.
   - Token Key Cache can now be customized via `XsuaaTokenAuthenticator`
   - `XSUserInfoAdapter` supports `requestTokenForUser()` method
diff --git a/api/pom.xml b/api/pom.xml
index 0a67c448..c2cb0b6d 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -8,7 +8,7 @@
 	<parent>
 		<groupId>com.sap.cloud.security.xsuaa</groupId>
 		<artifactId>parent</artifactId>
-		<version>2.7.4</version>
+		<version>2.7.5</version>
 	</parent>
 
 	<packaging>jar</packaging>
diff --git a/api/src/main/java/com/sap/xsa/security/container/XSUserInfo.java b/api/src/main/java/com/sap/xsa/security/container/XSUserInfo.java
index e25ce960..9dca93be 100644
--- a/api/src/main/java/com/sap/xsa/security/container/XSUserInfo.java
+++ b/api/src/main/java/com/sap/xsa/security/container/XSUserInfo.java
@@ -78,9 +78,11 @@ public interface XSUserInfo {
 	String getOrigin() throws XSUserInfoException;
 
 	/**
-	 * Return identity zone which is in most cases same like the subaccount identifier.
+	 * Return identity zone which is in most cases same like the subaccount
+	 * identifier.
 	 * 
-	 * @deprecated Have to be replaced with {@link #getZoneId()} or {@link #getSubaccountId()}.
+	 * @deprecated Have to be replaced with {@link #getZoneId()} or
+	 *             {@link #getSubaccountId()}.
 	 * @return identity zone
 	 * @throws XSUserInfoException
 	 *             if attribute is not available in the authentication token
@@ -91,8 +93,8 @@ public interface XSUserInfo {
 	/**
 	 * Return subaccount identifier.
 	 *
-	 * DO only use this for metering purposes.
-	 * DO NOT longer use this method to get the unique tenant id! For that use {@link #getZoneId()}.
+	 * DO only use this for metering purposes. DO NOT longer use this method to get
+	 * the unique tenant id! For that use {@link #getZoneId()}.
 	 *
 	 * @return subaccount identifier
 	 * @throws XSUserInfoException
@@ -101,12 +103,12 @@ public interface XSUserInfo {
 	String getSubaccountId() throws XSUserInfoException;
 
 	/**
-	 * Return zone identifier which should be used as tenant discriminator (tenant id).
-	 * For most of the old subaccounts this matches the id returned by {@link #getSubaccountId()}.
+	 * Return zone identifier which should be used as tenant discriminator (tenant
+	 * id). For most of the old subaccounts this matches the id returned by
+	 * {@link #getSubaccountId()}.
 	 *
-	 * @deprecated Can be replaced with
-	 *             {@code token.getZoneId()} from
-	 *             the {@code com.sap.cloud.security.token} package.
+	 * @deprecated Can be replaced with {@code token.getZoneId()} from the
+	 *             {@code com.sap.cloud.security.token} package.
 	 * @return zone identifier
 	 * @throws XSUserInfoException
 	 *             if attribute is not available in the authentication token
diff --git a/java-api/pom.xml b/java-api/pom.xml
index 565928d1..836b0545 100644
--- a/java-api/pom.xml
+++ b/java-api/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>com.sap.cloud.security.xsuaa</groupId>
 		<artifactId>parent</artifactId>
-		<version>2.7.4</version>
+		<version>2.7.5</version>
 	</parent>
 
 	<groupId>com.sap.cloud.security</groupId>
diff --git a/java-api/src/main/java/com/sap/cloud/security/config/Service.java b/java-api/src/main/java/com/sap/cloud/security/config/Service.java
index 24e5a8e3..37a5b0ea 100644
--- a/java-api/src/main/java/com/sap/cloud/security/config/Service.java
+++ b/java-api/src/main/java/com/sap/cloud/security/config/Service.java
@@ -28,7 +28,7 @@ public enum Service {
 	 */
 	public String getCFName() {
 		if (this == IAS && cloudFoundryName == null) {
-			LoggerFactory.getLogger(Service.class).error("IAS Service is not yet supported!!!"); // TODO remove
+			LoggerFactory.getLogger(Service.class).info("IAS Service is not yet supported!!!"); // TODO remove
 		}
 		return cloudFoundryName;
 	}
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 87f8a2f1..6f51316b 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
@@ -141,9 +141,9 @@ public interface Token {
 	 **/
 	Set<String> getAudiences();
 
-
 	/**
-	 * Returns the Zone identifier, which can be used as tenant discriminator (tenant guid).
+	 * Returns the Zone identifier, which can be used as tenant discriminator
+	 * (tenant guid).
 	 *
 	 * @return the unique Zone identifier.
 	 */
diff --git a/java-security/Migration_SAPJavaBuildpackProjects.md b/java-security/Migration_SAPJavaBuildpackProjects.md
index 030f0039..aaba9fd7 100644
--- a/java-security/Migration_SAPJavaBuildpackProjects.md
+++ b/java-security/Migration_SAPJavaBuildpackProjects.md
@@ -43,9 +43,29 @@ Whether the token is issued for your application or not is now validated by the
 
 ### Congratulation! With that you're Done!
 
+### Troubleshooting
 
-### Get stuck with migration
-[Open an issue on Github](https://github.com/SAP/cloud-security-xsuaa-integration/issues/new) and provide details like client-lib / migration guide / issue you’re facing.
+If you run into issues with the migration of your application, you can increase the logging level. 
+This helps to identify the root cause of the issue. In the buildpack this can be done by setting the `SET_LOGGING_LEVEL`
+environment variable for your application. You can do this in the `manifest.yml` with the `env` option like so:
+
+```yaml
+env:
+    SET_LOGGING_LEVEL: '{com.sap.xs.security: DEBUG, com.sap.cloud.security: DEBUG}'
+```
+After you have made changes to the `manifest.yml` you need do re-deploy your app.
+This sets the logging level for this library and the security parts of the buildpack to `DEBUG`.
+For a running application this can also be done with the `cf` command line tool:
+
+```shell
+cf set-env <your app name> SET_LOGGING_LEVEL "{com.sap.xs.security: DEBUG, com.sap.cloud.security: DEBUG}"
+```
+
+You need to restage your application for the changes to take effect.
+
+If you are still stuck with migration, please
+[open an issue on Github](https://github.com/SAP/cloud-security-xsuaa-integration/issues/new)
+and provide details like client-lib / migration guide / issue you’re facing and, when available, (debug) logs.
 
 ### [OPTIONAL] Leverage new API and features
 You can continue [here](Migration_SAPJavaBuildpackProjects_V2.md) to understand what needs to be done to leverage the new `java-api` that is exposed by the SAP Java Buildpack as of version `1.26.1`.
diff --git a/java-security/Migration_SpringSecurityProjects.md b/java-security/Migration_SpringSecurityProjects.md
index 13a6a155..8379e820 100644
--- a/java-security/Migration_SpringSecurityProjects.md
+++ b/java-security/Migration_SpringSecurityProjects.md
@@ -37,19 +37,19 @@ First make sure you have the following dependencies defined in your pom.xml:
 <dependency>
   <groupId>com.sap.cloud.security.xsuaa</groupId>
   <artifactId>api</artifactId>
-  <version>2.7.4</version>
+  <version>2.7.5</version>
 </dependency>
 <dependency>
   <groupId>com.sap.cloud.security</groupId>
   <artifactId>java-security</artifactId>
-  <version>2.7.4</version>
+  <version>2.7.5</version>
 </dependency>
 
 <!-- new java-security dependencies for unit tests -->
 <dependency>
   <groupId>com.sap.cloud.security</groupId>
   <artifactId>java-security-test</artifactId>
-  <version>2.7.4</version>
+  <version>2.7.5</version>
   <scope>test</scope>
 </dependency>
 ```
diff --git a/java-security/README.md b/java-security/README.md
index 7e088ec2..dc9fe4c7 100644
--- a/java-security/README.md
+++ b/java-security/README.md
@@ -44,7 +44,7 @@ Token Validation for Java applications.
 <dependency>
     <groupId>com.sap.cloud.security</groupId>
     <artifactId>java-security</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
 </dependency>
 <dependency>
     <groupId>org.apache.httpcomponents</groupId>
diff --git a/java-security/pom.xml b/java-security/pom.xml
index 26fc2d5e..498c3d62 100644
--- a/java-security/pom.xml
+++ b/java-security/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>com.sap.cloud.security.xsuaa</groupId>
 		<artifactId>parent</artifactId>
-		<version>2.7.4</version>
+		<version>2.7.5</version>
 	</parent>
 
 	<groupId>com.sap.cloud.security</groupId>
diff --git a/java-security/src/main/java/com/sap/cloud/security/adapter/xs/XSUserInfoAdapter.java b/java-security/src/main/java/com/sap/cloud/security/adapter/xs/XSUserInfoAdapter.java
index 61c8332b..24d41128 100644
--- a/java-security/src/main/java/com/sap/cloud/security/adapter/xs/XSUserInfoAdapter.java
+++ b/java-security/src/main/java/com/sap/cloud/security/adapter/xs/XSUserInfoAdapter.java
@@ -128,12 +128,14 @@ public class XSUserInfoAdapter implements XSUserInfo {
 	 * "ext_attr": { "enhancer": "XSUAA", "subaccountid": "my-subaccount-1234" },
 	 */
 	public String getSubaccountId() {
-		return Optional.ofNullable(getExternalAttribute(EXTERNAL_ATTRIBUTE_SUBACCOUNTID)).orElse(getClaimValue(ZONE_ID));
+		return Optional.ofNullable(getExternalAttribute(EXTERNAL_ATTRIBUTE_SUBACCOUNTID))
+				.orElse(getClaimValue(ZONE_ID));
 	}
 
 	@Override
 	public String getZoneId() {
-		return accessToken.hasClaim(SAP_GLOBAL_ZONE_ID) ? accessToken.getClaimAsString(SAP_GLOBAL_ZONE_ID) : getClaimValue(ZONE_ID);
+		return accessToken.hasClaim(SAP_GLOBAL_ZONE_ID) ? accessToken.getClaimAsString(SAP_GLOBAL_ZONE_ID)
+				: getClaimValue(ZONE_ID);
 	}
 
 	@Override
diff --git a/java-security/src/main/java/com/sap/cloud/security/config/OAuth2ServiceConfigurationBuilder.java b/java-security/src/main/java/com/sap/cloud/security/config/OAuth2ServiceConfigurationBuilder.java
index 45d0f1b5..4b78c323 100644
--- a/java-security/src/main/java/com/sap/cloud/security/config/OAuth2ServiceConfigurationBuilder.java
+++ b/java-security/src/main/java/com/sap/cloud/security/config/OAuth2ServiceConfigurationBuilder.java
@@ -166,5 +166,14 @@ public class OAuth2ServiceConfigurationBuilder {
 		public int hashCode() {
 			return Objects.hash(properties, runInLegacyMode, service);
 		}
+
+		@Override
+		public String toString() {
+			return "OAuth2ServiceConfigurationImpl{" +
+					"properties=" + properties +
+					", service=" + service +
+					", legacyMode=" + isLegacyMode() +
+					'}';
+		}
 	}
 }
\ No newline at end of file
diff --git a/java-security/src/main/java/com/sap/cloud/security/json/DefaultJsonObject.java b/java-security/src/main/java/com/sap/cloud/security/json/DefaultJsonObject.java
index 1c206505..b2abea12 100644
--- a/java-security/src/main/java/com/sap/cloud/security/json/DefaultJsonObject.java
+++ b/java-security/src/main/java/com/sap/cloud/security/json/DefaultJsonObject.java
@@ -190,4 +190,8 @@ public class DefaultJsonObject implements JsonObject {
 		}
 	}
 
+	@Override
+	public String toString() {
+		return jsonObject.toString(2);
+	}
 }
diff --git a/java-security/src/main/java/com/sap/cloud/security/token/AbstractToken.java b/java-security/src/main/java/com/sap/cloud/security/token/AbstractToken.java
index f80dc479..61028ca1 100644
--- a/java-security/src/main/java/com/sap/cloud/security/token/AbstractToken.java
+++ b/java-security/src/main/java/com/sap/cloud/security/token/AbstractToken.java
@@ -27,12 +27,14 @@ import static com.sap.cloud.security.token.TokenClaims.XSUAA.ISSUED_AT;
  * header parameters and claims.
  */
 public abstract class AbstractToken implements Token {
+	private final DecodedJwt decodedJwt;
 	protected final DefaultJsonObject tokenHeader;
 	protected final DefaultJsonObject tokenBody;
-	protected final String jwtToken;
 
 	public AbstractToken(@Nonnull DecodedJwt decodedJwt) {
-		this(decodedJwt.getHeader(), decodedJwt.getPayload(), decodedJwt.getEncodedToken());
+		this.tokenHeader = new DefaultJsonObject(decodedJwt.getHeader());
+		this.tokenBody = new DefaultJsonObject(decodedJwt.getPayload());
+		this.decodedJwt = decodedJwt;
 	}
 
 	/**
@@ -47,12 +49,6 @@ public abstract class AbstractToken implements Token {
 		this(Base64JwtDecoder.getInstance().decode(removeBearer(jwtToken)));
 	}
 
-	AbstractToken(String jsonHeader, String jsonPayload, String jwtToken) {
-		tokenHeader = new DefaultJsonObject(jsonHeader);
-		tokenBody = new DefaultJsonObject(jsonPayload);
-		this.jwtToken = jwtToken;
-	}
-
 	@Nullable
 	@Override
 	public String getHeaderParameterAsString(@Nonnull String headerName) {
@@ -109,7 +105,7 @@ public abstract class AbstractToken implements Token {
 
 	@Override
 	public String getTokenValue() {
-		return jwtToken;
+		return decodedJwt.getEncodedToken();
 	}
 
 	@Override
@@ -168,4 +164,9 @@ public abstract class AbstractToken implements Token {
 	public String getZoneId() {
 		return getClaimAsString(TokenClaims.SAP_GLOBAL_ZONE_ID);
 	}
+
+	@Override
+	public String toString() {
+		return decodedJwt.toString();
+	}
 }
diff --git a/java-security/src/main/java/com/sap/cloud/security/token/validation/CombiningValidator.java b/java-security/src/main/java/com/sap/cloud/security/token/validation/CombiningValidator.java
index bdec1599..a1358d97 100644
--- a/java-security/src/main/java/com/sap/cloud/security/token/validation/CombiningValidator.java
+++ b/java-security/src/main/java/com/sap/cloud/security/token/validation/CombiningValidator.java
@@ -1,11 +1,10 @@
 package com.sap.cloud.security.token.validation;
 
 import com.sap.cloud.security.xsuaa.Assertions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  * This is a special validator that combines several validators into one. By
@@ -16,6 +15,7 @@ import java.util.Set;
  */
 public class CombiningValidator<T> implements Validator<T> {
 
+	private static final Logger LOGGER = LoggerFactory.getLogger(CombiningValidator.class);
 	private final List<Validator<T>> validators;
 	private final Set<ValidationListener> validationListeners = new HashSet<>();
 
@@ -34,6 +34,7 @@ public class CombiningValidator<T> implements Validator<T> {
 		for (Validator<T> validator : validators) {
 			ValidationResult result = validator.validate(t);
 			if (result.isErroneous()) {
+				debugLog(t, validator);
 				validationListeners.forEach(listener -> listener.onValidationError(result));
 				return result;
 			}
@@ -41,18 +42,6 @@ public class CombiningValidator<T> implements Validator<T> {
 		return createValidationResult();
 	}
 
-	private ValidationResult createValidationResult() {
-		if (validators.isEmpty()) {
-			ValidationResult result = ValidationResults
-					.createInvalid("CombiningValidator must contain at least one validator!");
-			validationListeners.forEach(listener -> listener.onValidationError(result));
-			return result;
-		} else {
-			validationListeners.forEach(ValidationListener::onValidationSuccess);
-			return ValidationResults.createValid();
-		}
-	}
-
 	public List<Validator<T>> getValidators() {
 		return validators;
 	}
@@ -88,4 +77,25 @@ public class CombiningValidator<T> implements Validator<T> {
 	public void removeValidationListener(ValidationListener validationListener) {
 		validationListeners.remove(validationListener);
 	}
+
+	private void debugLog(T t, Validator<T> validator) {
+		if (LOGGER.isDebugEnabled()) {
+			String objectType = t == null ? "null" : t.getClass().getName();
+			LOGGER.debug("Validator that caused the failed validation: {}", validator.getClass().getName());
+			LOGGER.debug("Object of type {} that caused the failed validation: {}{}", objectType,
+					System.lineSeparator(), t);
+		}
+	}
+
+	private ValidationResult createValidationResult() {
+		if (validators.isEmpty()) {
+			ValidationResult result = ValidationResults
+					.createInvalid("CombiningValidator must contain at least one validator!");
+			validationListeners.forEach(listener -> listener.onValidationError(result));
+			return result;
+		} else {
+			validationListeners.forEach(ValidationListener::onValidationSuccess);
+			return ValidationResults.createValid();
+		}
+	}
 }
diff --git a/java-security/src/main/java/com/sap/cloud/security/token/validation/validators/JwtAudienceValidator.java b/java-security/src/main/java/com/sap/cloud/security/token/validation/validators/JwtAudienceValidator.java
index b103c074..dd1369f2 100644
--- a/java-security/src/main/java/com/sap/cloud/security/token/validation/validators/JwtAudienceValidator.java
+++ b/java-security/src/main/java/com/sap/cloud/security/token/validation/validators/JwtAudienceValidator.java
@@ -44,7 +44,7 @@ public class JwtAudienceValidator implements Validator<Token> {
 	public ValidationResult validate(Token token) {
 		Set<String> allowedAudiences = extractAudiencesFromToken(token);
 
-		if(validateDefault(allowedAudiences)
+		if (validateDefault(allowedAudiences)
 				|| validateAudienceOfXsuaaBrokerClone(allowedAudiences)) {
 			return ValidationResults.createValid();
 		}
@@ -115,8 +115,9 @@ public class JwtAudienceValidator implements Validator<Token> {
 	}
 
 	/**
-	 * In case of audiences, the namespaces are trimmed.
-	 * In case of scopes, the namespaces and the scope names are trimmed.
+	 * In case of audiences, the namespaces are trimmed. In case of scopes, the
+	 * namespaces and the scope names are trimmed.
+	 * 
 	 * @param scopeOrAudience
 	 * @return
 	 */
diff --git a/pom.xml b/pom.xml
index 02843870..530b4c37 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 
 	<groupId>com.sap.cloud.security.xsuaa</groupId>
 	<artifactId>parent</artifactId>
-	<version>2.7.4</version>
+	<version>2.7.5</version>
 	<packaging>pom</packaging>
 
 	<name>parent</name>
diff --git a/samples/java-security-usage/pom.xml b/samples/java-security-usage/pom.xml
index 1dfec4bc..ab4d8607 100755
--- a/samples/java-security-usage/pom.xml
+++ b/samples/java-security-usage/pom.xml
@@ -3,13 +3,13 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sap.cloud.security.xssec.samples</groupId>
     <artifactId>java-security-usage</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
     <packaging>jar</packaging>
 
     <properties>
         <maven.compiler.source>1.8</maven.compiler.source>
         <maven.compiler.target>1.8</maven.compiler.target>
-        <sap.cloud.security.version>2.7.4</sap.cloud.security.version>
+        <sap.cloud.security.version>2.7.5</sap.cloud.security.version>
         <slf4j.api.version>1.7.30</slf4j.api.version>
         <apache.httpclient.version>4.5.8</apache.httpclient.version>
         <javax.servlet.api.version>3.1.0</javax.servlet.api.version>
diff --git a/samples/java-tokenclient-usage/pom.xml b/samples/java-tokenclient-usage/pom.xml
index d8c645b9..33ca2e99 100755
--- a/samples/java-tokenclient-usage/pom.xml
+++ b/samples/java-tokenclient-usage/pom.xml
@@ -3,13 +3,13 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.sap.cloud.security.xssec.samples</groupId>
     <artifactId>java-tokenclient-usage</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
     <packaging>war</packaging>
 
     <properties>
         <maven.compiler.source>1.8</maven.compiler.source>
         <maven.compiler.target>1.8</maven.compiler.target>
-        <sap.cloud.security.version>2.7.4</sap.cloud.security.version>
+        <sap.cloud.security.version>2.7.5</sap.cloud.security.version>
         <apache.httpclient.version>4.5.8</apache.httpclient.version>
         <javax.servlet.api.version>3.0.1</javax.servlet.api.version>
     </properties>
diff --git a/samples/sap-java-buildpack-api-usage/manifest.yml b/samples/sap-java-buildpack-api-usage/manifest.yml
index 7ea2000f..be769dd1 100644
--- a/samples/sap-java-buildpack-api-usage/manifest.yml
+++ b/samples/sap-java-buildpack-api-usage/manifest.yml
@@ -17,6 +17,7 @@ applications:
   services:
     - xsuaa-buildpack
   env:
+    SET_LOGGING_LEVEL: '{com.sap.xs.security: DEBUG, com.sap.cloud.security: DEBUG}'
     ENABLE_SECURITY_JAVA_API_V2: true
 # Application Router as web server
 - name: approuter-sap-java-buildpack-api-usage
diff --git a/samples/sap-java-buildpack-api-usage/pom.xml b/samples/sap-java-buildpack-api-usage/pom.xml
index 2602f8fe..ba29bba9 100755
--- a/samples/sap-java-buildpack-api-usage/pom.xml
+++ b/samples/sap-java-buildpack-api-usage/pom.xml
@@ -3,7 +3,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>com.sap.cloud.security.xssec.samples</groupId>
 	<artifactId>sap-java-buildpack-api-usage</artifactId>
-	<version>2.7.4</version>
+	<version>2.7.5</version>
 	<packaging>war</packaging>
 
 	<properties>
diff --git a/samples/spring-security-basic-auth/pom.xml b/samples/spring-security-basic-auth/pom.xml
index 963641f0..cc191934 100644
--- a/samples/spring-security-basic-auth/pom.xml
+++ b/samples/spring-security-basic-auth/pom.xml
@@ -11,14 +11,14 @@
 	</parent>
 
 	<artifactId>spring-security-basic-auth</artifactId>
-	<version>2.7.4</version>
+	<version>2.7.5</version>
 	<name>spring-security-basic-auth</name>
 
 	<properties>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 		<java.version>1.8</java.version>
-		<sap.cloud.security.version>2.7.4</sap.cloud.security.version>
+		<sap.cloud.security.version>2.7.5</sap.cloud.security.version>
 	</properties>
 
 	<dependencies>
diff --git a/samples/spring-security-xsuaa-usage/pom.xml b/samples/spring-security-xsuaa-usage/pom.xml
index 4c504ebf..eea6c75e 100644
--- a/samples/spring-security-xsuaa-usage/pom.xml
+++ b/samples/spring-security-xsuaa-usage/pom.xml
@@ -14,7 +14,7 @@
 
 	<groupId>com.sap.cloud.security.samples</groupId>
 	<artifactId>spring-security-xsuaa-usage</artifactId>
-	<version>2.7.4</version>
+	<version>2.7.5</version>
 	<name>spring-security-xsuaa-usage</name>
 
 	<properties>
@@ -27,7 +27,7 @@
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 		<java.version>1.8</java.version>
-		<sap.cloud.security.version>2.7.4</sap.cloud.security.version>
+		<sap.cloud.security.version>2.7.5</sap.cloud.security.version>
 	</properties>
 
     <dependencies>
diff --git a/samples/spring-webflux-security-xsuaa-usage/pom.xml b/samples/spring-webflux-security-xsuaa-usage/pom.xml
index 3577d96d..b262ef03 100644
--- a/samples/spring-webflux-security-xsuaa-usage/pom.xml
+++ b/samples/spring-webflux-security-xsuaa-usage/pom.xml
@@ -12,12 +12,12 @@
 
     <groupId>com.sap.cloud.security.samples</groupId>
     <artifactId>spring-webflux-security-xsuaa-usage</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
     <name>spring-webflux-security-xsuaa-usage</name>
 
     <properties>
         <java.version>1.8</java.version>
-        <sap.cloud.security.version>2.7.4</sap.cloud.security.version>
+        <sap.cloud.security.version>2.7.5</sap.cloud.security.version>
     </properties>
 
     <dependencies>
diff --git a/spring-xsuaa-it/pom.xml b/spring-xsuaa-it/pom.xml
index 7bc49eec..1a0666ea 100644
--- a/spring-xsuaa-it/pom.xml
+++ b/spring-xsuaa-it/pom.xml
@@ -6,7 +6,7 @@
 	<parent>
 		<groupId>com.sap.cloud.security.xsuaa</groupId>
 		<artifactId>parent</artifactId>
-		<version>2.7.4</version>
+		<version>2.7.5</version>
 	</parent>
 
 	<artifactId>spring-xsuaa-it</artifactId>
diff --git a/spring-xsuaa-mock/README.md b/spring-xsuaa-mock/README.md
index f6966162..bb1614a9 100644
--- a/spring-xsuaa-mock/README.md
+++ b/spring-xsuaa-mock/README.md
@@ -21,7 +21,7 @@ The default implementation offers already valid *token_keys* for JWT tokens, tha
 <dependency>
     <groupId>com.sap.cloud.security.xsuaa</groupId>
     <artifactId>spring-xsuaa-mock</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
 </dependency>
 <dependency> <!-- new with version 1.5.0 - provided with org.springframework.boot:spring-boot-starter:jar -->
     <groupId>org.springframework.boot</groupId>
diff --git a/spring-xsuaa-mock/pom.xml b/spring-xsuaa-mock/pom.xml
index 95c84fdd..8d5fa3ab 100644
--- a/spring-xsuaa-mock/pom.xml
+++ b/spring-xsuaa-mock/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>com.sap.cloud.security.xsuaa</groupId>
 		<artifactId>parent</artifactId>
-		<version>2.7.4</version>
+		<version>2.7.5</version>
 	</parent>
 
 	<artifactId>spring-xsuaa-mock</artifactId>
diff --git a/spring-xsuaa-starter/pom.xml b/spring-xsuaa-starter/pom.xml
index c920e462..9587b955 100644
--- a/spring-xsuaa-starter/pom.xml
+++ b/spring-xsuaa-starter/pom.xml
@@ -14,7 +14,7 @@
 	<parent>
 		<groupId>com.sap.cloud.security.xsuaa</groupId>
 		<artifactId>parent</artifactId>
-		<version>2.7.4</version>
+		<version>2.7.5</version>
 	</parent>
 
 	<artifactId>xsuaa-spring-boot-starter</artifactId>
diff --git a/spring-xsuaa/README.md b/spring-xsuaa/README.md
index 47fe261e..52dbf26a 100644
--- a/spring-xsuaa/README.md
+++ b/spring-xsuaa/README.md
@@ -25,7 +25,7 @@ These (spring) dependencies needs to be provided:
 <dependency>
     <groupId>com.sap.cloud.security.xsuaa</groupId>
     <artifactId>spring-xsuaa</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
 </dependency>
 <dependency> <!-- new with version 1.5.0 -->
     <groupId>org.apache.logging.log4j</groupId>
@@ -40,7 +40,7 @@ These (spring) dependencies needs to be provided:
 <dependency>
     <groupId>com.sap.cloud.security.xsuaa</groupId>
     <artifactId>xsuaa-spring-boot-starter</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
 </dependency>
 ```
 
diff --git a/spring-xsuaa/pom.xml b/spring-xsuaa/pom.xml
index fd461b8a..17114723 100644
--- a/spring-xsuaa/pom.xml
+++ b/spring-xsuaa/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>com.sap.cloud.security.xsuaa</groupId>
 		<artifactId>parent</artifactId>
-		<version>2.7.4</version>
+		<version>2.7.5</version>
 	</parent>
 
 	<artifactId>spring-xsuaa</artifactId>
diff --git a/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/token/Token.java b/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/token/Token.java
index 4f440ae7..72114536 100644
--- a/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/token/Token.java
+++ b/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/token/Token.java
@@ -20,18 +20,18 @@ public interface Token extends UserDetails {
 	static final String GRANTTYPE_CLIENTCREDENTIAL = "client_credentials";
 
 	/**
-	 * Return subaccount identifier which is in most cases same like the
-	 * identity zone.
-	 * DO only use this for metering purposes.
-	 * DO NOT longer use this method to get the unique tenant id! For that use {@link #getZoneId()}.
+	 * Return subaccount identifier which is in most cases same like the identity
+	 * zone. DO only use this for metering purposes. DO NOT longer use this method
+	 * to get the unique tenant id! For that use {@link #getZoneId()}.
 	 *
 	 * @return the subaccount identifier.
 	 */
 	String getSubaccountId();
 
 	/**
-	 * Return zone identifier which should be used as tenant discriminator (tenant id).
-	 * For most of the old subaccounts this matches the id returned by {@link #getSubaccountId()}.
+	 * Return zone identifier which should be used as tenant discriminator (tenant
+	 * id). For most of the old subaccounts this matches the id returned by
+	 * {@link #getSubaccountId()}.
 	 *
 	 * @return the zone identifier.
 	 */
diff --git a/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/token/authentication/XsuaaJwtDecoder.java b/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/token/authentication/XsuaaJwtDecoder.java
index 52088de0..8d3baa83 100644
--- a/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/token/authentication/XsuaaJwtDecoder.java
+++ b/spring-xsuaa/src/main/java/com/sap/cloud/security/xsuaa/token/authentication/XsuaaJwtDecoder.java
@@ -140,7 +140,8 @@ public class XsuaaJwtDecoder implements JwtDecoder {
 				logger.warn("Error: Do not trust jku '{}' because it does not match uaa domain '{}'.",
 						jku, uaadomain);
 				throw new JwtException("Do not trust 'jku' token header.");
-			} else if (!jkuUri.getPath().endsWith("token_keys") || !isEmpty(jkuUri.getQuery()) || !isEmpty(jkuUri.getFragment())) {
+			} else if (!jkuUri.getPath().endsWith("token_keys") || !isEmpty(jkuUri.getQuery())
+					|| !isEmpty(jkuUri.getFragment())) {
 				logger.warn("Error: Do not trust jku '{}' because it contains invalid path, query or fragment.", jku);
 				throw new JwtException("Jwt token does not contain a valid 'jku' header parameter: " + jkuUri);
 			}
diff --git a/token-client/README.md b/token-client/README.md
index 8216c96f..163d19aa 100644
--- a/token-client/README.md
+++ b/token-client/README.md
@@ -23,7 +23,7 @@ The Resource owner password credentials (i.e., username and password) can be use
 <dependency>
     <groupId>com.sap.cloud.security.xsuaa</groupId>
     <artifactId>token-client</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
 </dependency>
 <dependency>
   <groupId>org.apache.httpcomponents</groupId>
@@ -62,7 +62,7 @@ By default, the `DefaultOAuth2TokenService` caches tokens internally. The Cache
 <dependency>
     <groupId>com.sap.cloud.security.xsuaa</groupId>
     <artifactId>token-client</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
 </dependency>
 ```
 
@@ -91,7 +91,7 @@ In context of a Spring Boot application you may like to leverage auto-configurat
 <dependency>
     <groupId>com.sap.cloud.security.xsuaa</groupId>
     <artifactId>xsuaa-spring-boot-starter</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
 </dependency>
 ```
 
diff --git a/token-client/pom.xml b/token-client/pom.xml
index 701f1ef1..e45f9c16 100644
--- a/token-client/pom.xml
+++ b/token-client/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>com.sap.cloud.security.xsuaa</groupId>
 		<artifactId>parent</artifactId>
-		<version>2.7.4</version>
+		<version>2.7.5</version>
 	</parent>
 
 	<artifactId>token-client</artifactId>
diff --git a/token-client/src/main/java/com/sap/cloud/security/xsuaa/client/AbstractOAuth2TokenService.java b/token-client/src/main/java/com/sap/cloud/security/xsuaa/client/AbstractOAuth2TokenService.java
index 1c10a28a..388cbe22 100644
--- a/token-client/src/main/java/com/sap/cloud/security/xsuaa/client/AbstractOAuth2TokenService.java
+++ b/token-client/src/main/java/com/sap/cloud/security/xsuaa/client/AbstractOAuth2TokenService.java
@@ -241,7 +241,7 @@ public abstract class AbstractOAuth2TokenService implements OAuth2TokenService,
 	}
 
 	private void logDebug(OAuth2TokenResponse response) {
-		if(!LOGGER.isDebugEnabled()){
+		if (!LOGGER.isDebugEnabled()) {
 			return;
 		}
 		try {
diff --git a/token-client/src/main/java/com/sap/cloud/security/xsuaa/jwt/DecodedJwt.java b/token-client/src/main/java/com/sap/cloud/security/xsuaa/jwt/DecodedJwt.java
index ef040f34..9ccab0f6 100644
--- a/token-client/src/main/java/com/sap/cloud/security/xsuaa/jwt/DecodedJwt.java
+++ b/token-client/src/main/java/com/sap/cloud/security/xsuaa/jwt/DecodedJwt.java
@@ -4,7 +4,8 @@ package com.sap.cloud.security.xsuaa.jwt;
  * A Jwt token consists of three parts, separated by ".":
  * header.payload.signature
  *
- * Use {@code Base64JwtDecoder.getInstance().decode(token)} to get a {@link DecodedJwt} instance.
+ * Use {@code Base64JwtDecoder.getInstance().decode(token)} to get a
+ * {@link DecodedJwt} instance.
  */
 
 public interface DecodedJwt {


Test patch:
diff --git a/java-security-test/README.md b/java-security-test/README.md
index 913f461e..359d3c80 100644
--- a/java-security-test/README.md
+++ b/java-security-test/README.md
@@ -22,7 +22,7 @@ It includes for example a `JwtGenerator` that generates JSON Web Tokens (JWT) th
 <dependency>
     <groupId>com.sap.cloud.security</groupId>
     <artifactId>java-security-test</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
     <scope>test</scope>
 </dependency>
 ```
diff --git a/java-security-test/pom.xml b/java-security-test/pom.xml
index 2cfed338..efcd9b41 100644
--- a/java-security-test/pom.xml
+++ b/java-security-test/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>com.sap.cloud.security.xsuaa</groupId>
 		<artifactId>parent</artifactId>
-		<version>2.7.4</version>
+		<version>2.7.5</version>
 	</parent>
 
 	<groupId>com.sap.cloud.security</groupId>
diff --git a/java-security/src/test/java/com/sap/cloud/security/token/AbstractTokenTest.java b/java-security/src/test/java/com/sap/cloud/security/token/AbstractTokenTest.java
index 354838ba..ebdc44fd 100644
--- a/java-security/src/test/java/com/sap/cloud/security/token/AbstractTokenTest.java
+++ b/java-security/src/test/java/com/sap/cloud/security/token/AbstractTokenTest.java
@@ -124,4 +124,19 @@ public class AbstractTokenTest {
 		assertThat(cut.getClaimAsJsonObject("doesNotExist")).isNull();
 	}
 
+	@Test
+	public void toString_doesNotContainEncodedToken() {
+		assertThat(cut.toString()).doesNotContain(cut.getTokenValue());
+	}
+
+	@Test
+	public void toString_containsTokenContent() {
+		assertThat(cut.toString())
+				.contains(cut.getHeaderParameterAsString(TokenHeader.JWKS_URL))
+				.contains(cut.getHeaderParameterAsString(TokenHeader.KEY_ID))
+				.contains(cut.getAudiences())
+				.contains(cut.getClaimAsString(TokenClaims.XSUAA.CLIENT_ID))
+				.contains(cut.getClaimAsString(TokenClaims.XSUAA.GRANT_TYPE))
+				.contains(cut.getClaimAsStringList(TokenClaims.XSUAA.SCOPES));
+	}
 }
\ No newline at end of file
diff --git a/java-security/src/test/java/com/sap/cloud/security/token/validation/validators/JwtAudienceValidatorTest.java b/java-security/src/test/java/com/sap/cloud/security/token/validation/validators/JwtAudienceValidatorTest.java
index dedaf933..9e31d0cf 100644
--- a/java-security/src/test/java/com/sap/cloud/security/token/validation/validators/JwtAudienceValidatorTest.java
+++ b/java-security/src/test/java/com/sap/cloud/security/token/validation/validators/JwtAudienceValidatorTest.java
@@ -100,7 +100,8 @@ public class JwtAudienceValidatorTest {
 	@Test
 	public void validate_tokenClientIdMatchesTrustedBrokerClientId() {
 		Mockito.when(token.getAudiences()).thenReturn(Collections.emptySet());
-		Mockito.when(token.getClaimAsString(TokenClaims.XSUAA.CLIENT_ID)).thenReturn("sb-clone-app-id!b123|" + XSUAA_BROKER_XSAPPNAME);
+		Mockito.when(token.getClaimAsString(TokenClaims.XSUAA.CLIENT_ID))
+				.thenReturn("sb-clone-app-id!b123|" + XSUAA_BROKER_XSAPPNAME);
 
 		// configures audience validator with client-id from VCAP_SERVICES
 		ValidationResult result = new JwtAudienceValidator(XSUAA_BROKER_XSAPPNAME)
@@ -112,7 +113,8 @@ public class JwtAudienceValidatorTest {
 	@Test
 	public void validate_tokenClientIdDoesNotMatchTrustedBrokerClientId() {
 		Mockito.when(token.getAudiences()).thenReturn(Collections.emptySet());
-		Mockito.when(token.getClaimAsString(TokenClaims.XSUAA.CLIENT_ID)).thenReturn("sb-clone-app-id!b123|-" + XSUAA_BROKER_XSAPPNAME);
+		Mockito.when(token.getClaimAsString(TokenClaims.XSUAA.CLIENT_ID))
+				.thenReturn("sb-clone-app-id!b123|-" + XSUAA_BROKER_XSAPPNAME);
 
 		// configures audience validator with client-id from VCAP_SERVICES
 		ValidationResult result = new JwtAudienceValidator(XSUAA_BROKER_XSAPPNAME)
@@ -191,5 +193,4 @@ public class JwtAudienceValidatorTest {
 		assertThat(audiences).containsExactlyInAnyOrder("test1!t1", "client", "xsappid");
 	}
 
-
 }
\ No newline at end of file
diff --git a/java-security/src/test/java/com/sap/cloud/security/token/validation/validators/XsuaaJwtIssuerValidatorTest.java b/java-security/src/test/java/com/sap/cloud/security/token/validation/validators/XsuaaJwtIssuerValidatorTest.java
index 57a02c05..b3075272 100644
--- a/java-security/src/test/java/com/sap/cloud/security/token/validation/validators/XsuaaJwtIssuerValidatorTest.java
+++ b/java-security/src/test/java/com/sap/cloud/security/token/validation/validators/XsuaaJwtIssuerValidatorTest.java
@@ -71,7 +71,8 @@ public class XsuaaJwtIssuerValidatorTest {
 		when(token.getHeaderParameterAsString(JWKS_URL)).thenReturn("\0://myauth.com");
 		ValidationResult validationResult = cut.validate(token);
 		assertThat(validationResult.isErroneous(), is(true));
-		assertThat(validationResult.getErrorDescription(), containsString("Jwt token does not contain a valid uri as 'jku' header parameter"));
+		assertThat(validationResult.getErrorDescription(),
+				containsString("Jwt token does not contain a valid uri as 'jku' header parameter"));
 	}
 
 	@Test
@@ -79,31 +80,38 @@ public class XsuaaJwtIssuerValidatorTest {
 		when(token.getHeaderParameterAsString(JWKS_URL)).thenReturn("\0://myauth.com");
 		ValidationResult validationResult = cut.validate(token);
 		assertThat(validationResult.isErroneous(), is(true));
-		assertThat(validationResult.getErrorDescription(), containsString("Jwt token does not contain a valid uri as 'jku' header parameter"));
+		assertThat(validationResult.getErrorDescription(),
+				containsString("Jwt token does not contain a valid uri as 'jku' header parameter"));
 	}
 
 	@Test
 	public void validationFails_whenJwksDoesNotContainAValidPath() {
-		when(token.getHeaderParameterAsString(JWKS_URL)).thenReturn("https://subdomain.myauth.ondemand.com/wrong_endpoint");
+		when(token.getHeaderParameterAsString(JWKS_URL))
+				.thenReturn("https://subdomain.myauth.ondemand.com/wrong_endpoint");
 		ValidationResult validationResult = cut.validate(token);
 		assertThat(validationResult.isErroneous(), is(true));
-		assertThat(validationResult.getErrorDescription(), containsString("Jwt token does not contain a valid 'jku' header parameter"));
+		assertThat(validationResult.getErrorDescription(),
+				containsString("Jwt token does not contain a valid 'jku' header parameter"));
 	}
 
 	@Test
 	public void validationFails_whenJwksContainQueryParameters() {
-		when(token.getHeaderParameterAsString(JWKS_URL)).thenReturn("https://subdomain.myauth.ondemand.com/token_keys?a=b");
+		when(token.getHeaderParameterAsString(JWKS_URL))
+				.thenReturn("https://subdomain.myauth.ondemand.com/token_keys?a=b");
 		ValidationResult validationResult = cut.validate(token);
 		assertThat(validationResult.isErroneous(), is(true));
-		assertThat(validationResult.getErrorDescription(), containsString("Jwt token does not contain a valid 'jku' header parameter"));
+		assertThat(validationResult.getErrorDescription(),
+				containsString("Jwt token does not contain a valid 'jku' header parameter"));
 	}
 
 	@Test
 	public void validationFails_whenJwksContainsFragment() {
-		when(token.getHeaderParameterAsString(JWKS_URL)).thenReturn("https://subdomain.myauth.ondemand.com/token_keys#token_keys");
+		when(token.getHeaderParameterAsString(JWKS_URL))
+				.thenReturn("https://subdomain.myauth.ondemand.com/token_keys#token_keys");
 		ValidationResult validationResult = cut.validate(token);
 		assertThat(validationResult.isErroneous(), is(true));
-		assertThat(validationResult.getErrorDescription(), containsString("Jwt token does not contain a valid 'jku' header parameter"));
+		assertThat(validationResult.getErrorDescription(),
+				containsString("Jwt token does not contain a valid 'jku' header parameter"));
 	}
 
 }
diff --git a/spring-xsuaa-test/README.md b/spring-xsuaa-test/README.md
index 3cf19eff..5139b762 100644
--- a/spring-xsuaa-test/README.md
+++ b/spring-xsuaa-test/README.md
@@ -27,7 +27,7 @@ This includes for example a `JwtGenerator` that generates JSON Web Tokens (JWT)
 <dependency>
     <groupId>com.sap.cloud.security.xsuaa</groupId>
     <artifactId>spring-xsuaa-test</artifactId>
-    <version>2.7.4</version>
+    <version>2.7.5</version>
     <scope>test</scope>
 </dependency>
 
diff --git a/spring-xsuaa-test/pom.xml b/spring-xsuaa-test/pom.xml
index eb9f4c82..b5f3a1db 100644
--- a/spring-xsuaa-test/pom.xml
+++ b/spring-xsuaa-test/pom.xml
@@ -7,7 +7,7 @@
 	<parent>
 		<groupId>com.sap.cloud.security.xsuaa</groupId>
 		<artifactId>parent</artifactId>
-		<version>2.7.4</version>
+		<version>2.7.5</version>
 	</parent>
 
 	<artifactId>spring-xsuaa-test</artifactId>
diff --git a/spring-xsuaa/src/test/java/com/sap/cloud/security/xsuaa/token/authentication/XsuaaJwtDecoderTest.java b/spring-xsuaa/src/test/java/com/sap/cloud/security/xsuaa/token/authentication/XsuaaJwtDecoderTest.java
index ecf5c204..a0a512b1 100644
--- a/spring-xsuaa/src/test/java/com/sap/cloud/security/xsuaa/token/authentication/XsuaaJwtDecoderTest.java
+++ b/spring-xsuaa/src/test/java/com/sap/cloud/security/xsuaa/token/authentication/XsuaaJwtDecoderTest.java
@@ -57,7 +57,7 @@ public class XsuaaJwtDecoderTest {
 	public void decode_whenJwksContainsInvalidJwksDomain_throwsException() throws IOException {
 		String token = IOUtils.resourceToString("/token_user.txt", StandardCharsets.UTF_8);
 
-		XsuaaJwtDecoder cut = (XsuaaJwtDecoder)new XsuaaJwtDecoderBuilder(configuration).build();
+		XsuaaJwtDecoder cut = (XsuaaJwtDecoder) new XsuaaJwtDecoderBuilder(configuration).build();
 		cut.setTokenInfoExtractor(new TokenInfoExtractorImpl("https://subdomain.wrongoauth.ondemand.com/token_keys"));
 
 		assertThatThrownBy(() -> cut.decode(token)).isInstanceOf(JwtException.class)
@@ -68,7 +68,7 @@ public class XsuaaJwtDecoderTest {
 	public void decode_whenJwksContainsInvalidPath_throwsException() throws IOException {
 		String token = IOUtils.resourceToString("/token_cc.txt", StandardCharsets.UTF_8);
 
-		XsuaaJwtDecoder cut = (XsuaaJwtDecoder)new XsuaaJwtDecoderBuilder(configuration).build();
+		XsuaaJwtDecoder cut = (XsuaaJwtDecoder) new XsuaaJwtDecoderBuilder(configuration).build();
 		cut.setTokenInfoExtractor(new TokenInfoExtractorImpl("https://subdomain.myauth.ondemand.com/wrong_endpoint"));
 
 		assertThatThrownBy(() -> cut.decode(token)).isInstanceOf(JwtException.class)
@@ -79,7 +79,7 @@ public class XsuaaJwtDecoderTest {
 	public void decode_whenJwksContainQueryParameters_throwsException() throws IOException {
 		String token = IOUtils.resourceToString("/token_cc.txt", StandardCharsets.UTF_8);
 
-		XsuaaJwtDecoder cut = (XsuaaJwtDecoder)new XsuaaJwtDecoderBuilder(configuration).build();
+		XsuaaJwtDecoder cut = (XsuaaJwtDecoder) new XsuaaJwtDecoderBuilder(configuration).build();
 		cut.setTokenInfoExtractor(new TokenInfoExtractorImpl("https://subdomain.myauth.ondemand.com/token_keys?a=b"));
 
 		assertThatThrownBy(() -> cut.decode(token)).isInstanceOf(JwtException.class)
@@ -91,15 +91,17 @@ public class XsuaaJwtDecoderTest {
 	public void decode_whenJwksContainsFragment_throwsException() throws IOException {
 		String token = IOUtils.resourceToString("/token_cc.txt", StandardCharsets.UTF_8);
 
-		XsuaaJwtDecoder cut = (XsuaaJwtDecoder)new XsuaaJwtDecoderBuilder(configuration).build();
-		cut.setTokenInfoExtractor(new TokenInfoExtractorImpl("https://subdomain.myauth.ondemand.com/token_keys#token_keys"));
+		XsuaaJwtDecoder cut = (XsuaaJwtDecoder) new XsuaaJwtDecoderBuilder(configuration).build();
+		cut.setTokenInfoExtractor(
+				new TokenInfoExtractorImpl("https://subdomain.myauth.ondemand.com/token_keys#token_keys"));
 
 		assertThatThrownBy(() -> cut.decode(token)).isInstanceOf(JwtException.class)
 				.hasMessageContaining("Jwt token does not contain a valid 'jku' header parameter:");
 
 	}
 
-	private static class TokenInfoExtractorImpl implements com.sap.cloud.security.xsuaa.token.authentication.TokenInfoExtractor {
+	private static class TokenInfoExtractorImpl
+			implements com.sap.cloud.security.xsuaa.token.authentication.TokenInfoExtractor {
 		private String jku;
 
 		public TokenInfoExtractorImpl(String jku) {