[java-plugin-shibd-oidc] branch main updated: JSHIBDOIDC-10 - Seal the access_token and refresh_token

Codeberg noreply at shibboleth.net
Wed Dec 3 16:48:25 UTC 2025


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

codeberg pushed a commit to branch main
in repository java-plugin-shibd-oidc.

View the commit online:
https://codeberg.org/Shibboleth/java-plugin-shibd-oidc/commit/b987d90709639933e06574bb92dfe9affe15e410

The following commit(s) were added to refs/heads/main by this push:
     new b987d90  JSHIBDOIDC-10 - Seal the access_token and refresh_token
b987d90 is described below

commit b987d90709639933e06574bb92dfe9affe15e410
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Wed Dec 3 16:48:10 2025 +0000

    JSHIBDOIDC-10 - Seal the access_token and refresh_token
    
     - Still need to return a DDF for the session data
    
    https://shibboleth.atlassian.net/browse/JSHIBDOIDC-10
---
 .../idp/flows/sp/consumer/oidc/oidc-beans.xml      |  3 +-
 .../sp/oidc/profile/impl/PrepareAgentResponse.java | 60 +++++++++++++++++++++-
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/sp-oidc-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/consumer/oidc/oidc-beans.xml b/sp-oidc-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/consumer/oidc/oidc-beans.xml
index dc98c8b..9cd44e5 100644
--- a/sp-oidc-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/consumer/oidc/oidc-beans.xml
+++ b/sp-oidc-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/consumer/oidc/oidc-beans.xml
@@ -553,6 +553,7 @@
     <bean id="ExtractOIDCClaims" class="net.shibboleth.sp.oidc.profile.impl.ExtractOIDCClaims" scope="prototype"/>
     
     <bean id="PrepareAgentResponse" class="net.shibboleth.sp.oidc.profile.impl.PrepareAgentResponse" scope="prototype"
-     p:attributeContextLookupStrategy-ref="shibboleth.ChildLookup.AttributeContextFromEndUserClaimsContext"/>
+     p:attributeContextLookupStrategy-ref="shibboleth.ChildLookup.AttributeContextFromEndUserClaimsContext"
+     p:dataSealer-ref="#{'%{sp.dataSealer:shibboleth.DataSealer}'.trim()}"/>
     
 </beans>
diff --git a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/PrepareAgentResponse.java b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/PrepareAgentResponse.java
index adad921..052ef6d 100644
--- a/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/PrepareAgentResponse.java
+++ b/sp-oidc-impl/src/main/java/net/shibboleth/sp/oidc/profile/impl/PrepareAgentResponse.java
@@ -17,6 +17,7 @@ package net.shibboleth.sp.oidc.profile.impl;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.navigate.ChildContextLookup;
 import org.opensaml.profile.action.ActionSupport;
@@ -32,7 +33,11 @@ import com.nimbusds.openid.connect.sdk.OIDCTokenResponse;
 import net.shibboleth.oidc.profile.context.AccessTokenResponseContext;
 import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.FunctionSupport;
 import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.security.DataSealer;
+import net.shibboleth.shared.security.DataSealerException;
+import net.shibboleth.sp.ddf.DDF;
 import net.shibboleth.sp.profile.AbstractTokenConsumerResponseAction;
 
 /**
@@ -58,6 +63,12 @@ public class PrepareAgentResponse extends AbstractTokenConsumerResponseAction {
     /** The stashed token response context. */
     @NonnullBeforeExec private AccessTokenResponseContext tokenResponseContext;
     
+    /** Optional data sealer to use. */
+    @Nullable private DataSealer dataSealer;
+    
+    /** A mapping function that maps parameters in access tokens to DDF parameters to include in the session data. */
+    @Nonnull private final Function<AccessToken, DDF> abitraryParameterMapper;
+    
     /**
      * Constructor.
      */
@@ -65,6 +76,19 @@ public class PrepareAgentResponse extends AbstractTokenConsumerResponseAction {
         accessTokenResponseContextLookupStrategy =
                 new ChildContextLookup<>(AccessTokenResponseContext.class).compose(
                         new InboundMessageContextLookup());
+        
+        abitraryParameterMapper = FunctionSupport.constant(null);
+    }
+    
+    /**
+     * Sets {@link DataSealer} to use.
+     * 
+     * @param sealer data sealer
+     */
+    public void setDataSealer(@Nullable final DataSealer sealer) {
+        checkSetterPreconditions();
+        
+        dataSealer = sealer;
     }
     
     /**
@@ -105,9 +129,43 @@ public class PrepareAgentResponse extends AbstractTokenConsumerResponseAction {
         if (tokenResponse != null) {
             final AccessToken accessToken = tokenResponse.getTokens().getAccessToken();
             final RefreshToken refreshToken = tokenResponse.getTokens().getRefreshToken();
+            
             log.debug("{} Storing access and refresh tokens in session data", getLogPrefix());
+            final DDF tokens = new DDF(null).structure();            
+
+            tokens.addmember("token_type").string(accessToken.getType().getValue());
+            tokens.addmember("expires_in").longinteger(accessToken.getLifetime());
+            if (accessToken.getScope() != null) {
+                tokens.addmember("scope").string(accessToken.getScope().toString());
+            }
+            if (accessToken.getIssuedTokenType() != null) {
+                tokens.addmember("issued_token_type").string(accessToken.getIssuedTokenType().getURI().toString());
+            }
             
-            //TODO do this. Into a DDF structure?
+            final DataSealer localDataSealer = dataSealer;
+            if (localDataSealer != null) {
+                try {
+                    tokens.addmember("access_token").string(localDataSealer.wrap(accessToken.getValue()));
+                } catch (final DataSealerException e) {
+                    log.debug("{} Error sealing access token for session data", getLogPrefix(), e);
+                    // Is not an error, but the access token won't be stored.
+                }
+            } else {
+                tokens.addmember("access_token").string(accessToken.getValue());
+            }
+            if (refreshToken != null) {
+                if (localDataSealer != null) {
+                    try {
+                        tokens.addmember("refresh_token").string(localDataSealer.wrap(refreshToken.getValue()));
+                    } catch (final DataSealerException e) {
+                        log.debug("{} Error sealing refresh token for session data", getLogPrefix(), e);
+                        // Is not an error, but the refresh token won't be stored.
+                    }
+                } else {
+                    tokens.addmember("refresh_token").string(refreshToken.getValue());
+                }
+            }
+            //return tokens;
         }
         return null;
     }

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


More information about the commits mailing list