[java-oidc-common] branch main updated: JOIDC-7 - Support JWT access tokens for code or implicit grants

Scott Cantor cantor.2 at osu.edu
Wed Apr 27 14:28:25 UTC 2022


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

scantor pushed a commit to branch main
in repository java-oidc-common.

View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=1fdca02d36b93ff3878dc9ca0088250d9edaa2b1

The following commit(s) were added to refs/heads/main by this push:
     new 1fdca02  JOIDC-7 - Support JWT access tokens for code or implicit grants
1fdca02 is described below

commit 1fdca02d36b93ff3878dc9ca0088250d9edaa2b1
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Apr 27 10:27:13 2022 -0400

    JOIDC-7 - Support JWT access tokens for code or implicit grants
    
    https://shibboleth.atlassian.net/browse/JOIDC-7
    
    Allow for missing aud claim.
    Adjust UserInfo profile config to add claims validator.
    Extend SSO config with access token type setting.
---
 .../jwt/claims/impl/AudienceClaimsValidator.java   | 24 ++++++++++---
 .../config/AbstractOIDCSSOConfiguration.java       | 39 ++++++++++++++++++++++
 .../profile/config/OIDCUserInfoConfiguration.java  | 36 ++------------------
 .../navigate/AccessTokenTypeLookupFunction.java    |  3 ++
 ...AbstractOAuth2TokenValidatingConfiguration.java |  2 +-
 .../config/OAuth2TokenAudienceConfiguration.java   |  1 -
 pom.xml                                            |  2 +-
 7 files changed, 66 insertions(+), 41 deletions(-)

diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/AudienceClaimsValidator.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/AudienceClaimsValidator.java
index 5ff8f5d..0a3e18d 100644
--- a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/AudienceClaimsValidator.java
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/AudienceClaimsValidator.java
@@ -35,8 +35,8 @@ import net.shibboleth.utilities.java.support.component.ComponentSupport;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 
 /**
- * Verifies the Audience (aud) claim contains the client_id of this client (as registered at the issuer). See
- * section 3.1.3.7 of OpenID Connect core 1.0. The audience is determined at runtime using an appropriate strategy.
+ * Verifies the Audience (aud) claim contains the appropriate value.
+ * The audience is determined at runtime using an appropriate strategy.
  */
 @ThreadSafeAfterInit
 public class AudienceClaimsValidator extends AbstractClaimsValidator{
@@ -44,6 +44,8 @@ public class AudienceClaimsValidator extends AbstractClaimsValidator{
     /** Strategy to find the audience value from the context.*/
     @NonnullAfterInit private BiFunction<ProfileRequestContext,JWTClaimsSet, String> audienceLookupStrategy;
     
+    /** Allow a missing aud claim. */
+    private boolean allowMissing;
     
     /** {@inheritDoc} */
     @Override
@@ -66,6 +68,19 @@ public class AudienceClaimsValidator extends AbstractClaimsValidator{
         
         audienceLookupStrategy = Constraint.isNotNull(strategy, "Audience lookup strategy can not be null");
     }
+    
+    /**
+     * Set whether a missing 'aud' claim is valid or not.
+     * 
+     * <p>Defaults to false.</p>
+     * 
+     * @param flag flag to set
+     * 
+     * @since 2.1.0
+     */
+    public void setAllowMissing(final boolean flag) {
+        allowMissing = flag;
+    }
 
     @Override
     protected void doValidate(@Nonnull final JWTClaimsSet claims, @Nonnull final ProfileRequestContext context) 
@@ -73,7 +88,7 @@ public class AudienceClaimsValidator extends AbstractClaimsValidator{
         
         final String acceptedAudience = audienceLookupStrategy.apply(context,claims);
         if (acceptedAudience == null) {
-            throw new JWTValidationException("Audience value not present in the context");
+            throw new JWTValidationException("Audience value not returned by lookup function");
         }
         
         final List<String> audList = claims.getAudience();
@@ -88,10 +103,9 @@ public class AudienceClaimsValidator extends AbstractClaimsValidator{
             if (!audMatch) {
                 throw new JWTValidationException("JWT audience rejected: " + audList);
             }
-        } else {
+        } else if (!allowMissing) {
             throw new JWTValidationException("JWT missing required audience");
         }
-        
     }
 
 }
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/AbstractOIDCSSOConfiguration.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/AbstractOIDCSSOConfiguration.java
index ce49d2c..95b3c7f 100644
--- a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/AbstractOIDCSSOConfiguration.java
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/AbstractOIDCSSOConfiguration.java
@@ -71,6 +71,9 @@ public abstract class AbstractOIDCSSOConfiguration extends AbstractOAuth2FlowAwa
     /** Lookup function to supply ID token lifetime. */
     @Nonnull private Function<ProfileRequestContext,Duration> idTokenLifetimeLookupStrategy;
 
+    /** Lookup functioon to supply access token type. */
+    @Nonnull private Function<ProfileRequestContext,String> accessTokenTypeLookupStrategy;
+    
     /** Lookup function to supply access token lifetime. */
     @Nonnull private Function<ProfileRequestContext,Duration> accessTokenLifetimeLookupStrategy;
     
@@ -98,6 +101,7 @@ public abstract class AbstractOIDCSSOConfiguration extends AbstractOAuth2FlowAwa
         allowPKCEPlainPredicate = Predicates.alwaysFalse();
         
         idTokenLifetimeLookupStrategy = FunctionSupport.constant(Duration.ofHours(1));
+        accessTokenTypeLookupStrategy = FunctionSupport.constant(null);
         accessTokenLifetimeLookupStrategy = FunctionSupport.constant(Duration.ofMinutes(10));
         refreshTokenLifetimeLookupStrategy = FunctionSupport.constant(Duration.ofHours(2));
         
@@ -278,6 +282,41 @@ public abstract class AbstractOIDCSSOConfiguration extends AbstractOAuth2FlowAwa
     public void setIDTokenLifetimeLookupStrategy(@Nonnull final Function<ProfileRequestContext,Duration> strategy) {
         idTokenLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
     }
+    
+    /**
+     * Get access token type.
+     * 
+     * @param profileRequestContext profile request context
+     * 
+     * @return access token type, or null for unspecified/opaque
+     * 
+     * @since 2.1.0
+     */
+     @Nullable @NotEmpty public String getAccessTokenType(@Nullable final ProfileRequestContext profileRequestContext) {
+         return accessTokenTypeLookupStrategy.apply(profileRequestContext);
+     }
+    
+    /**
+     * Set access token type.
+     * 
+     * @param type token type, or null for unspecified/opaque
+     * 
+     * @since 2.1.0
+     */
+     public void setAccessTokenType(@Nullable @NotEmpty final String type) {
+         accessTokenTypeLookupStrategy = FunctionSupport.constant(StringSupport.trimOrNull(type));
+     }
+    
+    /**
+     * Set lookup strategy for access token type.
+     * 
+     * @param strategy lookup strategy
+     * 
+     * @since 2.1.0
+     */
+     public void setAccessTokenTypeLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
+         accessTokenTypeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+     }
 
     /**
      * Get access token lifetime.
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCUserInfoConfiguration.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCUserInfoConfiguration.java
index 997be95..284ab67 100644
--- a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCUserInfoConfiguration.java
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCUserInfoConfiguration.java
@@ -30,9 +30,8 @@ import org.opensaml.profile.context.ProfileRequestContext;
 
 import com.google.common.base.Predicates;
 
-import net.shibboleth.idp.profile.config.AbstractConditionalProfileConfiguration;
 import net.shibboleth.idp.profile.config.AttributeResolvingProfileConfiguration;
-import net.shibboleth.idp.profile.config.OverriddenIssuerProfileConfiguration;
+import net.shibboleth.oidc.profile.oauth2.config.AbstractOAuth2TokenValidatingConfiguration;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
@@ -43,9 +42,8 @@ import net.shibboleth.utilities.java.support.primitive.StringSupport;
 /**
  * Profile configuration for the OpenID Connect core protocol userinfo endpoint.
  */
-public class OIDCUserInfoConfiguration extends AbstractConditionalProfileConfiguration
-        implements OIDCProfileConfiguration, OverriddenIssuerProfileConfiguration, 
-                        AttributeResolvingProfileConfiguration {
+public class OIDCUserInfoConfiguration extends AbstractOAuth2TokenValidatingConfiguration
+        implements AttributeResolvingProfileConfiguration {
 
     /** OIDC base protocol URI. */
     @Nonnull @NotEmpty public static final String PROTOCOL_URI = "http://openid.net/specs/openid-connect-core-1_0.html";
@@ -53,9 +51,6 @@ public class OIDCUserInfoConfiguration extends AbstractConditionalProfileConfigu
     /** ID for this profile configuration. */
     @Nonnull @NotEmpty public static final String PROFILE_ID = "http://shibboleth.net/ns/profiles/oidc/userinfo";
 
-    /** Lookup function to override issuer value. */
-    @Nonnull private Function<ProfileRequestContext,String> issuerLookupStrategy;
-
     /** Whether attributes should be resolved in the course of the profile. */
     @Nonnull private Predicate<ProfileRequestContext> resolveAttributesPredicate;
 
@@ -80,36 +75,11 @@ public class OIDCUserInfoConfiguration extends AbstractConditionalProfileConfigu
     public OIDCUserInfoConfiguration(@Nonnull @NotEmpty final String profileId) {
         super(profileId);
         
-        issuerLookupStrategy = FunctionSupport.constant(null);
         resolveAttributesPredicate = Predicates.alwaysTrue();
         encryptionOptionalPredicate = Predicates.alwaysTrue();
         deniedUserInfoAttributesLookupStrategy = FunctionSupport.constant(null);
     }
 
-    /** {@inheritDoc} */
-    @Override
-    @Nullable @NotEmpty public String getIssuer(@Nullable final ProfileRequestContext profileRequestContext) {
-        return issuerLookupStrategy.apply(profileRequestContext);
-    }
-    
-    /**
-     * Set overridden issuer value.
-     * 
-     * @param issuer issuer value
-     */
-    public void setIssuer(@Nullable @NotEmpty final String issuer) {
-        issuerLookupStrategy = FunctionSupport.constant(issuer);
-    }
-    
-    /**
-     * Sets lookup strategy for overridden issuer value.
-     * 
-     * @param strategy lookup strategy
-     */
-    public void setIssuerLookupStrategy(@Nonnull final Function<ProfileRequestContext,String> strategy) {
-        issuerLookupStrategy = Constraint.isNotNull(strategy, "Issuer lookup strategy cannot be null");
-    }
-
     /** {@inheritDoc} */
     @Override
     public boolean isResolveAttributes(@Nullable final ProfileRequestContext profileRequestContext) {
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/AccessTokenTypeLookupFunction.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/AccessTokenTypeLookupFunction.java
index 1693732..41a91ac 100644
--- a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/AccessTokenTypeLookupFunction.java
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/navigate/AccessTokenTypeLookupFunction.java
@@ -24,6 +24,7 @@ import org.opensaml.profile.context.ProfileRequestContext;
 import net.shibboleth.idp.profile.config.ProfileConfiguration;
 import net.shibboleth.idp.profile.context.RelyingPartyContext;
 import net.shibboleth.idp.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.oidc.profile.config.AbstractOIDCSSOConfiguration;
 import net.shibboleth.oidc.profile.oauth2.config.OAuth2TokenAudienceConfiguration;
 
 /**
@@ -44,6 +45,8 @@ public class AccessTokenTypeLookupFunction extends AbstractRelyingPartyLookupFun
             final ProfileConfiguration pc = rpc.getProfileConfig();
             if (pc instanceof OAuth2TokenAudienceConfiguration) {
                 return ((OAuth2TokenAudienceConfiguration) pc).getAccessTokenType(input);
+            } else if (pc instanceof AbstractOIDCSSOConfiguration) {
+                return ((AbstractOIDCSSOConfiguration) pc).getAccessTokenType(input);
             }
         }
         
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/AbstractOAuth2TokenValidatingConfiguration.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/AbstractOAuth2TokenValidatingConfiguration.java
index fae1ccb..e22c004 100644
--- a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/AbstractOAuth2TokenValidatingConfiguration.java
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/AbstractOAuth2TokenValidatingConfiguration.java
@@ -33,7 +33,7 @@ import net.shibboleth.utilities.java.support.logic.FunctionSupport;
 /**
  * Base class for profile configurations that validate previously issued OAuth2 tokens.
  * 
- * @since 3.1.0
+ * @since 2.0.0
  */
 public class AbstractOAuth2TokenValidatingConfiguration extends AbstractOAuth2ClientAuthenticableProfileConfiguration
         implements OverriddenIssuerProfileConfiguration {
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/OAuth2TokenAudienceConfiguration.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/OAuth2TokenAudienceConfiguration.java
index 2090b9e..6d0a9bf 100644
--- a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/OAuth2TokenAudienceConfiguration.java
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/oauth2/config/OAuth2TokenAudienceConfiguration.java
@@ -167,7 +167,6 @@ public class OAuth2TokenAudienceConfiguration  extends AbstractConditionalProfil
     public void setEncryptionOptionalPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
         encryptionOptionalPredicate = Constraint.isNotNull(condition, "Encryption optional predicate cannot be null");
     }
-
     
     /**
      * Get access token type.
diff --git a/pom.xml b/pom.xml
index 7041c93..f7986ba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>net.shibboleth</groupId>
         <artifactId>parent</artifactId>
-        <version>11.3.1</version>
+        <version>11.3.2</version>
     </parent>
     <groupId>net.shibboleth.oidc</groupId>
     <artifactId>oidc-common-parent</artifactId>

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


More information about the commits mailing list