[java-idp-oidc] branch main updated: JOIDC-194 - Logging improvements for message tracing

Henri Mikkonen henri.mikkonen at iki.fi
Thu Apr 4 08:19:57 UTC 2024


This is an automated email from the git hooks/post-receive script.

hjmikkon pushed a commit to branch main
in repository java-idp-oidc.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-oidc.git;a=commit;h=54f320e44daea47879bd039ae3f572f50a9551eb

The following commit(s) were added to refs/heads/main by this push:
     new 54f320e4 JOIDC-194 - Logging improvements for message tracing
54f320e4 is described below

commit 54f320e44daea47879bd039ae3f572f50a9551eb
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Apr 4 11:19:24 2024 +0300

    JOIDC-194 - Logging improvements for message tracing
    
    https://shibboleth.atlassian.net/browse/JOIDC-194
    
    Included JWT refresh token payload contents into protocol messages on TRACE.
---
 ...efaultJwtRefreshTokenSerializationFunction.java | 31 ++++++++++++++++++++++
 .../idp/flows/oidc/token/token-beans.xml           |  3 ++-
 ...ltJwtRefreshTokenSerializationFunctionTest.java |  2 ++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenSerializationFunction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenSerializationFunction.java
index 4a297fa1..9b2582e6 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenSerializationFunction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenSerializationFunction.java
@@ -14,6 +14,7 @@
 
 package net.shibboleth.idp.plugin.oidc.op.profile.logic;
 
+import java.text.ParseException;
 import java.util.Date;
 import java.util.function.BiFunction;
 import java.util.function.Function;
@@ -23,16 +24,19 @@ import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.MessageContext;
 import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.messaging.encoder.AbstractMessageEncoder;
 import org.opensaml.messaging.handler.MessageHandler;
 import org.opensaml.messaging.handler.MessageHandlerException;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
 import org.slf4j.Logger;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.nimbusds.jwt.JWTClaimsSet;
 import com.nimbusds.jwt.SignedJWT;
 import com.nimbusds.oauth2.sdk.id.ClientID;
 
+import net.shibboleth.idp.plugin.oidc.op.encoding.impl.ResponseUtil;
 import net.shibboleth.idp.plugin.oidc.op.token.support.RefreshTokenClaimsSet;
 import net.shibboleth.idp.plugin.oidc.op.token.support.TokenClaimsSet;
 import net.shibboleth.oidc.security.impl.JWSTokenSigner;
@@ -67,6 +71,10 @@ public class DefaultJwtRefreshTokenSerializationFunction extends AbstractInitial
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultJwtRefreshTokenSerializationFunction.class);
 
+    /** Used to log protocol messages. */
+    @Nonnull private Logger protocolMessageLog =
+            LoggerFactory.getLogger(AbstractMessageEncoder.BASE_PROTOCOL_MESSAGE_LOGGER_CATEGORY + ".OAUTH2");
+
     /** Data sealer for sealing private parts of the refresh token. */
     @NonnullAfterInit private DataSealer dataSealer;
 
@@ -82,6 +90,9 @@ public class DefaultJwtRefreshTokenSerializationFunction extends AbstractInitial
     /** Strategy to find the audience value from the context.*/
     @NonnullAfterInit private Function<ProfileRequestContext, String> audienceLookupStrategy;
 
+    /** Object mapper used for pretty-printing JWT contents. */
+    @NonnullAfterInit private ObjectMapper objectMapper;
+
     /**
      * Constructor.
      */
@@ -147,6 +158,16 @@ public class DefaultJwtRefreshTokenSerializationFunction extends AbstractInitial
         audienceLookupStrategy = Constraint.isNotNull(strategy, "Audience lookup strategy can not be null");
     }
 
+    /**
+     * Set the object mapper used for pretty-printing JWT contents.
+     * 
+     * @param mapper What to set.
+     */
+    public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+        checkSetterPreconditions();
+        objectMapper = Constraint.isNotNull(mapper, "Object mapper cannot be null");
+    }
+
     /** {@inheritDoc} */
     @Override
     protected void doInitialize() throws ComponentInitializationException {
@@ -164,6 +185,9 @@ public class DefaultJwtRefreshTokenSerializationFunction extends AbstractInitial
         if (audienceLookupStrategy == null) {
             throw new ComponentInitializationException("The audience lookup strategy cannot be null)");
         }
+        if (objectMapper == null) {
+            throw new ComponentInitializationException("Object mapper cannot be null");
+        }
     }
 
     /** {@inheritDoc} */
@@ -243,6 +267,13 @@ public class DefaultJwtRefreshTokenSerializationFunction extends AbstractInitial
         }
         assert jwtClaims != null;
         final JWSTokenSigner signer = new JWSTokenSigner(signingParameters);
+        try {
+            assert objectMapper != null;
+            protocolMessageLog.trace("JWT refresh token payload contents:\n{}",
+                    ResponseUtil.getJwtProtocolMessage(jwtClaims, objectMapper));
+        } catch (final ParseException e) {
+            log.error("Could not construct the protocol message of the JWT contents", e);
+        }
         try {
             return signer.sign(jwtClaims, typeHeader);
         } catch (final SignatureException e) {
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml
index a790ab8b..b5d5fa8b 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml
@@ -433,7 +433,8 @@
     <bean id="DefaultJwtRefreshTokenSerializationFunction"
         class="net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultJwtRefreshTokenSerializationFunction"
         scope="prototype"
-        p:dataSealer-ref="#{'%{idp.oidc.tokenSealer:shibboleth.oidc.TokenSealer}'.trim()}">
+        p:dataSealer-ref="#{'%{idp.oidc.tokenSealer:shibboleth.oidc.TokenSealer}'.trim()}"
+        p:objectMapper-ref="#{'%{idp.oidc.logging.objectMapper:shibboleth.oidc.JSONObjectMapper}'.trim()}">
         <property name="signingParametersHandler">
             <bean class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureSigningParametersHandler"
                 scope="prototype">
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenSerializationFunctionTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenSerializationFunctionTest.java
index 26d77a5b..64b9a693 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenSerializationFunctionTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/logic/DefaultJwtRefreshTokenSerializationFunctionTest.java
@@ -34,6 +34,7 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.nimbusds.jwt.SignedJWT;
 import com.nimbusds.oauth2.sdk.Scope;
 import com.nimbusds.oauth2.sdk.id.ClientID;
@@ -89,6 +90,7 @@ public class DefaultJwtRefreshTokenSerializationFunctionTest {
             function.setTypeHeaderLookupStrategy(typeHeaderLookupStrategy);
             assert audienceLookupStrategy != null;
             function.setAudienceLookupStrategy(audienceLookupStrategy);
+            function.setObjectMapper(new ObjectMapper());
             function.initialize();
         } catch (final ComponentInitializationException e) {
             Assert.fail("Could not initialize the function", e);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list