diff --git a/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptor.java b/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptor.java index 5e2dd5709e..bae88d060a 100644 --- a/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptor.java +++ b/core/src/main/java/com/predic8/membrane/core/interceptor/jwt/JwtAuthInterceptor.java @@ -31,9 +31,9 @@ import static org.apache.commons.text.StringEscapeUtils.*; /** - * @description Validates a JWT on requests (signature via JWKS, required exp/sub) and exposes claims in exchange properties ("jwt"). - * @yaml - *

+ * @description Validates a JWT on requests (signature via JWKS, required
+ * exp/sub) and exposes claims in exchange properties ("jwt").
+ * @yaml  

  *  jwtAuth:
  *    expectedAud: my-audience
  *    expectedTid: 67c859d3-0cd4-4a99-86db-088bed1a9601
@@ -65,7 +65,6 @@ public static String ERROR_JWT_VALUE_NOT_PRESENT(String key) {
     String expectedAud;
     String expectedTid;
 
-
     public JwtAuthInterceptor() {
         name = "jwt checker.";
         setAppliedFlow(of(REQUEST));
@@ -74,8 +73,9 @@ public JwtAuthInterceptor() {
     @Override
     public void init() {
         super.init();
-        if(jwtRetriever == null)
-            jwtRetriever = new HeaderJwtRetriever("Authorization","Bearer");
+        if (jwtRetriever == null) {
+            jwtRetriever = new HeaderJwtRetriever("Authorization", "Bearer");
+        }
 
         jwks.init(router);
     }
@@ -101,12 +101,14 @@ public Outcome handleRequest(Exchange exc) {
                     .buildAndSetResponse(exc);
             return RETURN;
         } catch (InvalidJwtException e) {
+            log.error("JWT validation failed: {}", e.getMessage(), e);
             ProblemDetails.security(router.getConfiguration().isProduction(), "jwt-auth")
-                    .detail(ERROR_VALIDATION_FAILED)
+                    .detail(e.getMessage())
                     .addSubSee(ERROR_VALIDATION_FAILED_ID)
                     .stacktrace(false)
                     .status(400)
                     .buildAndSetResponse(exc);
+
             return RETURN;
         } catch (Exception e) {
             ProblemDetails.security(router.getConfiguration().isProduction(), "jwt-auth")
@@ -120,8 +122,9 @@ public Outcome handleRequest(Exchange exc) {
     }
 
     public Outcome handleJwt(Exchange exc, String jwt) throws JWTException, JsonProcessingException, InvalidJwtException {
-        if (jwt == null)
+        if (jwt == null) {
             throw new JWTException(ERROR_JWT_NOT_FOUND, ERROR_JWT_NOT_FOUND_ID);
+        }
 
         var decodedJwt = new JsonWebToken(jwt);
         var kid = decodedJwt.getHeader().kid();
@@ -132,7 +135,7 @@ public Outcome handleJwt(Exchange exc, String jwt) throws JWTException, JsonProc
 
         Map jwtClaims = createValidator(key).processToClaims(jwt).getClaimsMap();
 
-        exc.getProperties().put("jwt",jwtClaims);
+        exc.getProperties().put("jwt", jwtClaims);
 
         new JWTSecurityScheme(jwtClaims).add(exc);
 
@@ -146,17 +149,19 @@ private JwtConsumer createValidator(RsaJsonWebKey key) {
                 .setRequireSubject()
                 .setVerificationKey(key.getRsaPublicKey());
 
-        if (acceptAnyAud())
-            jwtConsumerBuilder.setSkipDefaultAudienceValidation();
-        else {
-            if (expectedAud != null && !expectedAud.isEmpty())
+        if (acceptAnyAud()) {
+            jwtConsumerBuilder.setSkipDefaultAudienceValidation(); 
+        }else {
+            if (expectedAud != null && !expectedAud.isEmpty()) {
                 jwtConsumerBuilder
                         .setExpectedAudience(expectedAud);
+            }
         }
 
-        if (expectedTid != null && !expectedTid.isEmpty())
+        if (expectedTid != null && !expectedTid.isEmpty()) {
             jwtConsumerBuilder
                     .registerValidator(new TidValidator(expectedTid));
+        }
 
         return jwtConsumerBuilder.build();
     }
@@ -193,8 +198,11 @@ public String getExpectedTid() {
 
     /**
      * @description
-     * 

Expected audience ('aud') value of the token.

- *

Use "any!!" to allow any audience value. This is strongly discouraged.

+ *

+ * Expected audience ('aud') value of the token.

+ *

+ * Use "any!!" to allow any audience value. This is strongly + * discouraged.

*/ @MCAttribute public void setExpectedAud(String expectedAud) { @@ -203,7 +211,8 @@ public void setExpectedAud(String expectedAud) { /** * @description - *

Expected tenant ID ('tid') value of the token.

+ *

+ * Expected tenant ID ('tid') value of the token.

* @default not set * @example 67c869d3-0cd4-4a99-86db-088bed1a9601 */ @@ -219,11 +228,11 @@ public String getShortDescription() { @Override public String getLongDescription() { - return "Checks for a valid JWT.
" + - (acceptAnyAud() ? - "Accepts any value for the aud field. THIS IS STRONGLY DISCOURAGED!
" : - "Accepts " + escapeHtml4(expectedAud) + " as valid value for the aud payload entry.
") + - (jwks != null ? "Validates the JWT signature against " + jwks.getLongDescription() + " ." : ""); + return "Checks for a valid JWT.
" + + (acceptAnyAud() + ? "Accepts any value for the aud field. THIS IS STRONGLY DISCOURAGED!
" + : "Accepts " + escapeHtml4(expectedAud) + " as valid value for the aud payload entry.
") + + (jwks != null ? "Validates the JWT signature against " + jwks.getLongDescription() + " ." : ""); } }