[java-idp-oidc] branch main updated: JOIDC-11 - Support for client_credentials grant

Scott Cantor cantor.2 at osu.edu
Mon Feb 14 17:54:38 UTC 2022


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

scantor 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=ebe201508a1a0c2c2f4040551676836d7dea9f06

The following commit(s) were added to refs/heads/main by this push:
     new ebe20150 JOIDC-11 - Support for client_credentials grant
ebe20150 is described below

commit ebe201508a1a0c2c2f4040551676836d7dea9f06
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Feb 14 12:54:35 2022 -0500

    JOIDC-11 - Support for client_credentials grant
    
    https://shibboleth.atlassian.net/browse/JOIDC-11
    
    Adjust auth method and grant type checks to allow for no metadata.
---
 .../impl/ValidateClientAuthenticationType.java     | 38 +++++++-------
 .../impl/AbstractOIDCTokenResponseAction.java      | 14 ++---
 .../oidc/op/profile/impl/ValidateGrantType.java    | 58 ++++++++++++++++++---
 .../idp/service/relying-party/postconfig.xml       | 60 ++++++++++------------
 .../idp/plugin/oidc/op/conf/oidc.properties        |  3 ++
 .../impl/ValidateClientAuthenticationTypeTest.java | 11 ++++
 .../impl/AbstractOIDCTokenResponseActionTest.java  | 11 ++--
 .../op/profile/impl/ValidateGrantTypeTest.java     | 47 ++++++++++++++---
 .../src/test/resources/conf/oidc.properties        |  2 +
 9 files changed, 165 insertions(+), 79 deletions(-)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationType.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationType.java
index e7006960..f508b043 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationType.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationType.java
@@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory;
 
 import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
 import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
 import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
 
 import net.shibboleth.idp.authn.AbstractAuthenticationAction;
@@ -50,6 +49,8 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
  * Validates the client authentication type with the token_endpoint_auth_method stored in the client's metadata
  * and the profile configuration.
  * 
+ * <p>In the absence of metadata, the profile configuration is used alone.</p>
+ * 
  * @pre {@link OIDCMetadataContext} is available
  * @pre AuthenticationContext.getSubcontext(OAuth2ClientAuthenticationContext.class) != null
  * @event {@link EventIds#PROCEED_EVENT_ID}
@@ -124,11 +125,6 @@ public class ValidateClientAuthenticationType extends AbstractAuthenticationActi
         }
 
         oidcMetadataContext = oidcMetadataContextLookupStrategy.apply(profileRequestContext);
-        if (oidcMetadataContext == null) {
-            log.warn("{} OICDMetadataContext is missing", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.ACCESS_DENIED);
-            return false;
-        }
         
         enabledMethods = tokenEndpointAuthMethodsLookupStrategy.apply(profileRequestContext);
         if (enabledMethods == null) {
@@ -143,27 +139,31 @@ public class ValidateClientAuthenticationType extends AbstractAuthenticationActi
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
             @Nonnull final AuthenticationContext authenticationContext) {
         
+        final ClientAuthenticationMethod registeredMethod;
+        
         // Pull the client's registered authn method, or default to client_secret_basic.
-        // The enabledMethods member contains the methods authorized in the configuration as a whole.
-        final OIDCClientInformation clientInformation = oidcMetadataContext.getClientInformation();
-        final OIDCClientMetadata clientMetadata = clientInformation.getOIDCMetadata();
-        final ClientAuthenticationMethod registeredMethod = clientMetadata.getTokenEndpointAuthMethod() != null ? 
-                clientMetadata.getTokenEndpointAuthMethod() : ClientAuthenticationMethod.CLIENT_SECRET_BASIC;
+        // If no metadata exists, leave null.
+        if (oidcMetadataContext != null && oidcMetadataContext.getClientInformation() != null) {
+            final OIDCClientMetadata clientMetadata = oidcMetadataContext.getClientInformation().getOIDCMetadata();
+            registeredMethod = clientMetadata.getTokenEndpointAuthMethod() != null ? 
+                    clientMetadata.getTokenEndpointAuthMethod() : ClientAuthenticationMethod.CLIENT_SECRET_BASIC;
+        } else {
+            registeredMethod = null;
+        }
 
         // Did the client use what it registered and is that still allowed?
-        
+        // The enabledMethods member contains the methods authorized in the configuration as a whole.
+
         final ClientAuthenticationMethod used =
-                clientAuthentication != null ? clientAuthentication.getMethod() : ClientAuthenticationMethod.NONE; 
-        if (!registeredMethod.equals(used)) {
+                clientAuthentication != null ? clientAuthentication.getMethod() : ClientAuthenticationMethod.NONE;
+        
+        if (registeredMethod != null && !registeredMethod.equals(used)) {
             log.warn("{} Client '{}' registered {} but attempted {}", getLogPrefix(),
                     clientAuthentication.getClientID(), registeredMethod, used);
             ActionSupport.buildEvent(profileRequestContext, EventIds.ACCESS_DENIED);
-            return;
-        } else if (!enabledMethods.contains(registeredMethod)) {
-            log.warn("{} Requested method {} is not enabled in profile configuration", getLogPrefix(),
-                    registeredMethod);
+        } else if (!enabledMethods.contains(used)) {
+            log.warn("{} Requested method {} not enabled in profile configuration", getLogPrefix(), used);
             ActionSupport.buildEvent(profileRequestContext, EventIds.ACCESS_DENIED);
-            return;
         }
     }
     
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractOIDCTokenResponseAction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractOIDCTokenResponseAction.java
index 3d38902d..128f0d3e 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractOIDCTokenResponseAction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractOIDCTokenResponseAction.java
@@ -80,19 +80,15 @@ abstract class AbstractOIDCTokenResponseAction extends AbstractOIDCTokenRequestA
             ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
             return false;
         }
-        oidcResponseContext = outboundMessageCtx.getSubcontext(OIDCAuthenticationResponseContext.class, false);
+        oidcResponseContext = outboundMessageCtx.getSubcontext(OIDCAuthenticationResponseContext.class);
         if (oidcResponseContext == null) {
-            log.error("{} No oidc response context", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
-            return false;
-        }
-        oidcMetadataContext =
-                profileRequestContext.getInboundMessageContext().getSubcontext(OIDCMetadataContext.class, false);
-        if (oidcMetadataContext == null) {
-            log.error("{} No metadata found for relying party", getLogPrefix());
+            log.error("{} No OIDC response context", getLogPrefix());
             ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
             return false;
         }
+        
+        oidcMetadataContext = profileRequestContext.getInboundMessageContext().getSubcontext(OIDCMetadataContext.class);
+        
         return true;
     }
 
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantType.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantType.java
index 729786ad..7742a652 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantType.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantType.java
@@ -17,8 +17,12 @@
 
 package net.shibboleth.idp.plugin.oidc.op.profile.impl;
 
+import java.util.Collections;
 import java.util.Set;
+import java.util.function.Function;
+
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.context.ProfileRequestContext;
@@ -27,7 +31,10 @@ import org.slf4j.LoggerFactory;
 import com.nimbusds.oauth2.sdk.AuthorizationGrant;
 import com.nimbusds.oauth2.sdk.GrantType;
 
-import net.shibboleth.idp.plugin.oidc.op.profile.OidcEventIds;
+import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCMetadataContext;
+import net.shibboleth.oidc.profile.config.navigate.GrantTypesLookupFunction;
+import net.shibboleth.oidc.profile.core.OidcEventIds;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
 
 /**
  * An action that validates the grant type is registered to the requesting RP. This action is used in Token end point to
@@ -38,15 +45,54 @@ public class ValidateGrantType extends AbstractOIDCTokenResponseAction {
     /** Class logger. */
     @Nonnull private Logger log = LoggerFactory.getLogger(ValidateGrantType.class);
 
+    /** Strategy to obtain enabled grant types. */
+    @Nonnull private Function<ProfileRequestContext,Set<GrantType>> grantTypesLookupStrategy;
+
+    /** Enabled grant types. */
+    @Nullable @NonnullElements private Set<GrantType> enabledTypes;
+    
+    /** Constructor. */
+    public ValidateGrantType() {
+        grantTypesLookupStrategy = new GrantTypesLookupFunction();
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+        if (!super.doPreExecute(profileRequestContext)) {
+            return false;
+        }
+        
+        enabledTypes = grantTypesLookupStrategy.apply(profileRequestContext);
+        if (enabledTypes == null) {
+            enabledTypes = Collections.emptySet();
+        }
+        
+        return true;
+    }
+    
     /** {@inheritDoc} */
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        final Set<GrantType> registeredTypes =
-                getMetadataContext().getClientInformation().getMetadata().getGrantTypes();
+        
+        final Set<GrantType> registeredTypes;
+        final OIDCMetadataContext metadataCtx = getMetadataContext();
+        if (metadataCtx != null) {
+            registeredTypes = getMetadataContext().getClientInformation().getMetadata().getGrantTypes();
+        } else {
+            registeredTypes = null;
+        }
+        
         final AuthorizationGrant grant = getTokenRequest().getAuthorizationGrant();
-        if (registeredTypes == null || registeredTypes.isEmpty() || !registeredTypes.contains(grant.getType())) {
-            log.error("{} The grant type {} is not registered for this RP", getLogPrefix(), grant.getType().getValue());
+
+        if (registeredTypes != null && !registeredTypes.contains(grant.getType())) {
+            log.error("{} Grant type {} not registered for client", getLogPrefix(), grant.getType().getValue());
+            ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_GRANT_TYPE);
+        } else if (!enabledTypes.contains(grant.getType())) {
+            log.error("{} Grant type {} not enabled in profile configuration", getLogPrefix(),
+                    grant.getType().getValue());
             ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_GRANT_TYPE);
         }
     }
-}
+
+}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
index 629616c2..1ccb0f55 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
@@ -39,7 +39,8 @@
         p:deniedUserInfoAttributes="%{idp.oidc.deniedUserInfoAttributes:}" />
 
     <bean id="OIDC.Token" parent="AbstractOIDCSSOProfile" lazy-init="true"
-        class="net.shibboleth.oidc.profile.config.OIDCTokenConfiguration" />
+        class="net.shibboleth.oidc.profile.config.OIDCTokenConfiguration"
+        p:grantTypes="%{idp.oauth2.grantTypes:authorization_code,refresh_token}" />
     
     <bean id="OIDC.UserInfo" parent="AbstractOIDCProfile" lazy-init="true"
         class="net.shibboleth.oidc.profile.config.OIDCUserInfoConfiguration"
@@ -193,6 +194,22 @@
                 <constructor-arg value="%{idp.oidc.encryptionOptional:true}" />
             </bean>
         </property>
+        <property name="forcePKCEPredicate">
+            <bean class="net.shibboleth.utilities.java.support.logic.PredicateSupport" factory-method="fromFunction">
+                <constructor-arg>
+                    <bean parent="shibboleth.MDDrivenBoolProperty" p:propertyName="forcePKCE" />
+                </constructor-arg>
+                <constructor-arg value="%{idp.oidc.forcePKCE:false}" />
+            </bean>
+        </property>
+        <property name="allowPKCEPlainPredicate">
+            <bean class="net.shibboleth.utilities.java.support.logic.PredicateSupport" factory-method="fromFunction">
+                <constructor-arg>
+                    <bean parent="shibboleth.MDDrivenBoolProperty" p:propertyName="allowPKCEPlain" />
+                </constructor-arg>
+                <constructor-arg value="%{idp.oidc.allowPKCEPlain:false}" />
+            </bean>
+        </property>
         <property name="iDTokenLifetimeLookupStrategy">
             <bean parent="shibboleth.MDDrivenDurationProperty" p:propertyName="iDTokenLifetime"
                 p:defaultValue="%{idp.oidc.idToken.defaultLifetime:PT1H}" />
@@ -241,7 +258,8 @@
             <bean parent="shibboleth.MDDrivenSetProperty" p:propertyName="encodedAttributes">
                 <property name="defaultValue">
                     <bean parent="shibboleth.CommaDelimStringArray">
-                        <constructor-arg type="java.lang.String" value="%{idp.oidc.encodedAttributes:%{idp.oidc.embeddedAttributes:}}" />
+                        <constructor-arg type="java.lang.String"
+                            value="%{idp.oidc.encodedAttributes:%{idp.oidc.embeddedAttributes:}}" />
                     </bean>
                 </property>
             </bean>
@@ -255,22 +273,6 @@
                 </property>
             </bean>
         </property>
-        <property name="forcePKCEPredicate">
-            <bean class="net.shibboleth.utilities.java.support.logic.PredicateSupport" factory-method="fromFunction">
-                <constructor-arg>
-                    <bean parent="shibboleth.MDDrivenBoolProperty" p:propertyName="forcePKCE" />
-                </constructor-arg>
-                <constructor-arg value="%{idp.oidc.forcePKCE:false}" />
-            </bean>
-        </property>
-        <property name="allowPKCEPlainPredicate">
-            <bean class="net.shibboleth.utilities.java.support.logic.PredicateSupport" factory-method="fromFunction">
-                <constructor-arg>
-                    <bean parent="shibboleth.MDDrivenBoolProperty" p:propertyName="allowPKCEPlain" />
-                </constructor-arg>
-                <constructor-arg value="%{idp.oidc.allowPKCEPlain:false}" />
-            </bean>
-        </property>
         <property name="refreshTokenLifetimeLookupStrategy">
             <bean parent="shibboleth.MDDrivenDurationProperty" p:propertyName="refreshTokenLifetime"
                 p:defaultValue="%{idp.oidc.refreshToken.defaultLifetime:PT2H}" />
@@ -279,20 +281,14 @@
     
     <bean id="OIDC.Token.MDDriven" parent="AbstractMDDrivenOIDCSSOProfile" lazy-init="true"
             class="net.shibboleth.oidc.profile.config.OIDCTokenConfiguration">
-        <property name="forcePKCEPredicate">
-            <bean class="net.shibboleth.utilities.java.support.logic.PredicateSupport" factory-method="fromFunction">
-                <constructor-arg>
-                    <bean parent="shibboleth.MDDrivenBoolProperty" p:propertyName="forcePKCE" />
-                </constructor-arg>
-                <constructor-arg value="%{idp.oidc.forcePKCE:false}" />
-            </bean>
-        </property>
-        <property name="allowPKCEPlainPredicate">
-            <bean class="net.shibboleth.utilities.java.support.logic.PredicateSupport" factory-method="fromFunction">
-                <constructor-arg>
-                    <bean parent="shibboleth.MDDrivenBoolProperty" p:propertyName="allowPKCEPlain" />
-                </constructor-arg>
-                <constructor-arg value="%{idp.oidc.allowPKCEPlain:false}" />
+        <property name="grantTypesLookupStrategy">
+            <bean parent="shibboleth.MDDrivenSetProperty" p:propertyName="grantTypes">
+                <property name="defaultValue">
+                    <bean parent="shibboleth.CommaDelimStringArray">
+                        <constructor-arg type="java.lang.String"
+                            value="%{idp.oauth2.grantTypes:authorization_code,refresh_token}" />
+                    </bean>
+                </property>
             </bean>
         </property>
         <property name="refreshTokenLifetimeLookupStrategy">
diff --git a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties
index ee6c0592..26523762 100644
--- a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties
+++ b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties
@@ -93,6 +93,9 @@ idp.oidc.subject.salt = this_too_should_be_ch4ng3d
 # OAuth2 Settings - these typically involve generic OAuth 2.0 use cases
 #
 
+# Supported grant_type values for token requests
+#idp.oauth2.grantTypes = authorization_code,refresh_token
+
 # Default handling of generic OAuth tokens (for use against arbitrary resource servers)
 #idp.oauth2.accessToken.defaultLifetime = PT10M
 # Set to JWT if desired as a default.
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationTypeTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationTypeTest.java
index d77d5968..44a5d1a0 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationTypeTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/authn/impl/ValidateClientAuthenticationTypeTest.java
@@ -148,4 +148,15 @@ public class ValidateClientAuthenticationTypeTest {
         ActionTestingSupport.assertProceedEvent(e);
     }
 
+    @Test
+    public void testNoMetadata() throws Exception {
+        initializeRequestCtx(ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
+                ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
+        prc.getInboundMessageContext().removeSubcontext(
+                prc.getInboundMessageContext().getSubcontext(OIDCMetadataContext.class));
+        enabledMethods = Collections.singleton(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
+        final Event e = action.execute(rc);
+        ActionTestingSupport.assertProceedEvent(e);
+    }
+
 }
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractOIDCTokenResponseActionTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractOIDCTokenResponseActionTest.java
index 93f0033c..da7101b6 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractOIDCTokenResponseActionTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractOIDCTokenResponseActionTest.java
@@ -19,7 +19,6 @@ package net.shibboleth.idp.plugin.oidc.op.profile.impl;
 
 import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
 import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCMetadataContext;
-import net.shibboleth.idp.plugin.oidc.op.profile.impl.AbstractOIDCTokenResponseAction;
 import net.shibboleth.idp.profile.context.navigate.WebflowRequestContextProfileRequestContextLookup;
 import net.shibboleth.idp.profile.testing.ActionTestingSupport;
 import net.shibboleth.idp.profile.testing.RequestContextBuilder;
@@ -58,10 +57,10 @@ public class AbstractOIDCTokenResponseActionTest {
         action = new MockOIDCTokenResponseAction();
         oIDCMetadataContext = new OIDCMetadataContext();
         oIDCAuthenticationResponseContext = new OIDCAuthenticationResponseContext();
-        AuthorizationCode code = new AuthorizationCode("xyz...");
-        URI callback = new URI("https://client.com/callback");
-        AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callback);
-        TokenRequest req = new TokenRequest(callback, new ClientID(), codeGrant);
+        final AuthorizationCode code = new AuthorizationCode("xyz...");
+        final URI callback = new URI("https://client.com/callback");
+        final AuthorizationGrant codeGrant = new AuthorizationCodeGrant(code, callback);
+        final TokenRequest req = new TokenRequest(callback, new ClientID(), codeGrant);
         requestCtx = new RequestContextBuilder().setInboundMessage(req).buildRequestContext();
         final MessageContext msgCtx = new MessageContext();
         prc = new WebflowRequestContextProfileRequestContextLookup().apply(requestCtx);
@@ -101,7 +100,7 @@ public class AbstractOIDCTokenResponseActionTest {
     public void testNoMetadataContext() throws Exception {
         prc.getInboundMessageContext().removeSubcontext(oIDCMetadataContext);
         final Event event = action.execute(requestCtx);
-        ActionTestingSupport.assertEvent(event, EventIds.INVALID_MSG_CTX);
+        ActionTestingSupport.assertProceedEvent(event);
     }
 
     /**
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantTypeTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantTypeTest.java
index a5e7a1db..8cfc8eed 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantTypeTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateGrantTypeTest.java
@@ -18,15 +18,15 @@
 package net.shibboleth.idp.plugin.oidc.op.profile.impl;
 
 import java.net.URI;
-import java.net.URISyntaxException;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
 import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCMetadataContext;
-import net.shibboleth.idp.plugin.oidc.op.profile.OidcEventIds;
-import net.shibboleth.idp.plugin.oidc.op.profile.impl.ValidateGrantType;
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
 import net.shibboleth.idp.profile.testing.ActionTestingSupport;
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.oidc.profile.config.OIDCTokenConfiguration;
+import net.shibboleth.oidc.profile.core.OidcEventIds;
 
 import org.springframework.webflow.execution.Event;
 import org.testng.annotations.BeforeMethod;
@@ -44,12 +44,16 @@ import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
 /** {@link ValidateGrantType} unit test. */
 public class ValidateGrantTypeTest extends BaseOIDCResponseActionTest {
 
+    /** Action to test. */
     private ValidateGrantType action;
 
+    /** Metadata. */
     private OIDCClientMetadata metaData;
 
+    /** Set up method. */ 
     @BeforeMethod
-    private void init() throws ComponentInitializationException, URISyntaxException, ParseException {
+    protected void setUp() throws Exception {
+        super.setUp();
         action = new ValidateGrantType();
         action.initialize();
         final OIDCMetadataContext oidcCtx =
@@ -72,16 +76,45 @@ public class ValidateGrantTypeTest extends BaseOIDCResponseActionTest {
      * Test that action accepts the "refresh_token" grant type.
      */
     @Test
-    public void testSuccess() throws ComponentInitializationException {
+    public void testSuccess() {
         final Event event = action.execute(requestCtx);
         ActionTestingSupport.assertProceedEvent(event);
     }
 
+    /**
+     * Test that action accepts the "refresh_token" grant type based on profile config.
+     */
+    @Test
+    public void testSuccessNoMetadata() {
+        profileRequestCtx.getInboundMessageContext().removeSubcontext(
+                profileRequestCtx.getInboundMessageContext().getSubcontext(OIDCMetadataContext.class));
+        final Event event = action.execute(requestCtx);
+        ActionTestingSupport.assertProceedEvent(event);
+    }
+
+    /**
+     * Test that action accepts the "refresh_token" grant type based on profile config.
+     */
+    @Test
+    public void testFailureNoMetadata() {
+        profileRequestCtx.getInboundMessageContext().removeSubcontext(
+                profileRequestCtx.getInboundMessageContext().getSubcontext(OIDCMetadataContext.class));
+        
+        final OIDCTokenConfiguration config = new OIDCTokenConfiguration();
+        config.setGrantTypes(Collections.singleton(GrantType.AUTHORIZATION_CODE.toString()));
+        profileRequestCtx.getSubcontext(RelyingPartyContext.class).setProfileConfig(config);
+        
+        final Event event = action.execute(requestCtx);
+        ActionTestingSupport.assertEvent(event, OidcEventIds.INVALID_GRANT_TYPE);
+    }
+
     /**
      * Test that action rejects the "refresh_token" grant type.
+     * 
+     * @throws ParseException 
      */
     @Test
-    public void testFailure() throws ComponentInitializationException, ParseException {
+    public void testFailure() throws ParseException {
         final Set<GrantType> grantTypes = new HashSet<>();
         grantTypes.add(GrantType.parse("authorization_code"));
         metaData.setGrantTypes(grantTypes);
diff --git a/idp-oidc-extension-impl/src/test/resources/conf/oidc.properties b/idp-oidc-extension-impl/src/test/resources/conf/oidc.properties
index 0163cbbe..f7bc0e70 100644
--- a/idp-oidc-extension-impl/src/test/resources/conf/oidc.properties
+++ b/idp-oidc-extension-impl/src/test/resources/conf/oidc.properties
@@ -7,3 +7,5 @@ idp.oidc.subject.salt = isfd07fsddfs70sdf9d99s8
 idp.oidc.discovery.template = src/test/resources/conf/openid-configuration.json
 
 idp.oidc.dynreg.defaultMetadataPolicyFile = src/test/resources/conf/metadata-policy1.json
+
+idp.oauth2.grantTypes = authorization_code,refresh_token,client_credentials
\ No newline at end of file

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


More information about the commits mailing list