[java-oidc-common] branch dev/JCOMOIDC-41 updated: Add JWT singing parameters to support authn request object signing

Phil Smart philip.smart at jisc.ac.uk
Fri Jul 1 13:04:02 UTC 2022


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

philsmart pushed a commit to branch dev/JCOMOIDC-41
in repository java-oidc-common.

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

The following commit(s) were added to refs/heads/dev/JCOMOIDC-41 by this push:
     new 28f0b79  Add JWT singing parameters to support authn request object signing
28f0b79 is described below

commit 28f0b79c5741b2bf7175b34f22de3a43b0ed1aa6
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Jul 1 14:03:53 2022 +0100

    Add JWT singing parameters to support authn request object signing
    
     - Some of the classes only exist to support the new
    JWTSecurityParametersContext. Perhaps we could refactor these out.
---
 .../context/JWTSecurityParametersContext.java      |  26 ++
 .../criterion/ClientInformationCriterion.java      |  54 ++++
 oidc-common-crypto-impl/pom.xml                    |   5 +
 .../PopulateJWTSignatureSigningParameters.java     | 216 +++++++++++++++
 ...pulateJWTSignatureSigningParametersHandler.java | 298 +++++++++++++++++++++
 .../PopulateJWTSignatureValidationParameters.java  |  10 +-
 .../profile/config/OIDCSecurityConfiguration.java  |  41 ++-
 .../profile/core/OAuthAuthorizationRequest.java    |  31 ++-
 8 files changed, 669 insertions(+), 12 deletions(-)

diff --git a/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/context/JWTSecurityParametersContext.java b/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/context/JWTSecurityParametersContext.java
index 220b4cc..08892ee 100644
--- a/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/context/JWTSecurityParametersContext.java
+++ b/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/context/JWTSecurityParametersContext.java
@@ -21,6 +21,7 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.BaseContext;
+import org.opensaml.xmlsec.SignatureSigningParameters;
 
 import com.nimbusds.jwt.SignedJWT;
 
@@ -36,6 +37,9 @@ public class JWTSecurityParametersContext extends BaseContext {
     /** Signature validation parameters. */
     @Nullable private SignatureValidationParameters<SignedJWT> signatureValidationParameters;
     
+    /** Signature signing parameters.*/
+    @Nullable private SignatureSigningParameters signatureSigningParameters;
+    
     /** Decryption parameters. */
     @Nullable private JWTDecryptionParameters decryptionParameters;
      
@@ -61,6 +65,28 @@ public class JWTSecurityParametersContext extends BaseContext {
         return this;
     }
     
+    /**
+     * Get the parameters to use for XML signature signing operations.
+     * 
+     * @return the parameters
+     */
+    @Nullable public SignatureSigningParameters getSignatureSigningParameters() {
+        return signatureSigningParameters;
+    }
+
+    /**
+     * Set the parameters to use for XML signature signing operations.
+     * 
+     * @param params the parameters
+     * 
+     * @return this context
+     */
+    @Nonnull public JWTSecurityParametersContext setSignatureSigningParameters(
+            @Nullable final SignatureSigningParameters params) {
+        signatureSigningParameters = params;
+        return this;
+    }
+    
     /**
      * Get the parameters to use for XML decryption operations.
      * 
diff --git a/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/criterion/ClientInformationCriterion.java b/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/criterion/ClientInformationCriterion.java
new file mode 100644
index 0000000..48ed46d
--- /dev/null
+++ b/oidc-common-crypto-api/src/main/java/net/shibboleth/oidc/security/criterion/ClientInformationCriterion.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.security.criterion;
+
+import javax.annotation.Nonnull;
+
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.resolver.Criterion;
+
+/**
+ * Client information criterion to make decisions based on client information. Usually used by
+ * {@link OIDCClientInformationSignatureSigningParametersResolver}.
+ */
+public class ClientInformationCriterion implements Criterion {
+
+    /** Client information. */
+    @Nonnull private final OIDCClientInformation oidcClientInformation;
+
+    /**
+     * Constructor.
+     * 
+     * @param information client information
+     */
+    public ClientInformationCriterion(@Nonnull final OIDCClientInformation information) {
+        oidcClientInformation = Constraint.isNotNull(information, "client information cannot be null");
+    }
+    
+    /**
+     * Get client information.
+     * 
+     * @return client information
+     */
+    @Nonnull public OIDCClientInformation getOidcClientInformation() {
+        return oidcClientInformation;
+    }
+
+}
\ No newline at end of file
diff --git a/oidc-common-crypto-impl/pom.xml b/oidc-common-crypto-impl/pom.xml
index 11c5f93..7aa04f9 100644
--- a/oidc-common-crypto-impl/pom.xml
+++ b/oidc-common-crypto-impl/pom.xml
@@ -40,6 +40,11 @@
             <artifactId>oidc-common-crypto-api</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>oidc-common-metadata-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>${opensaml.groupId}</groupId>
             <artifactId>opensaml-saml-api</artifactId>
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/PopulateJWTSignatureSigningParameters.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/PopulateJWTSignatureSigningParameters.java
new file mode 100644
index 0000000..0e94ba5
--- /dev/null
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/PopulateJWTSignatureSigningParameters.java
@@ -0,0 +1,216 @@
+package net.shibboleth.oidc.security.impl;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.messaging.context.navigate.ContextDataLookupFunction;
+import org.opensaml.profile.action.AbstractHandlerDelegatingProfileAction;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.opensaml.xmlsec.SecurityConfigurationSupport;
+import org.opensaml.xmlsec.SignatureSigningConfiguration;
+import org.opensaml.xmlsec.SignatureSigningParametersResolver;
+import org.opensaml.xmlsec.context.SecurityParametersContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
+import net.shibboleth.oidc.metadata.context.OIDCProviderMetadataContext;
+import net.shibboleth.oidc.security.context.JWTSecurityParametersContext;
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+public class PopulateJWTSignatureSigningParameters 
+    extends AbstractHandlerDelegatingProfileAction<PopulateJWTSignatureSigningParametersHandler> {
+    
+    /** Class logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(PopulateJWTSignatureSigningParameters.class);
+    
+    /** Strategy used to look up the {@link JWTSecurityParametersContext} to set the parameters for. */
+    @Nonnull private Function<ProfileRequestContext,JWTSecurityParametersContext> securityParametersContextLookupStrategy;
+    
+    /** Strategy used to look up an existing {@link JWTSecurityParametersContext} to copy. */
+    @Nullable private Function<ProfileRequestContext,JWTSecurityParametersContext> existingParametersContextLookupStrategy;
+    
+    /** Strategy used to look up a per-request {@link SignatureSigningConfiguration} list. */
+    @NonnullAfterInit 
+    private Function<ProfileRequestContext, List<SignatureSigningConfiguration>> configurationLookupStrategy;
+    
+    /** Strategy used to look up a OIDC client metadata context. */
+    @Nullable private Function<ProfileRequestContext, OIDCMetadataContext> oidcClientMetadataContextLookupStrategy;
+    
+    /** Strategy used to look up a OIDC provider metadata context. */
+    @Nullable 
+    private Function<ProfileRequestContext, OIDCProviderMetadataContext> oidcProviderMetadataContextLookupStrategy;
+    
+    /** Resolver for parameters to store into context. */
+    @NonnullAfterInit private SignatureSigningParametersResolver resolver;
+    
+    /** Whether failure to resolve parameters should be raised as an error. */
+    private boolean noResultIsError;
+
+    /**
+     * Constructor.
+     *
+     * @param strategy lookup strategy for message context
+     */
+    public PopulateJWTSignatureSigningParameters(@ParameterName(name = "strategy")
+            final ContextDataLookupFunction<ProfileRequestContext, MessageContext> strategy) {
+        super(PopulateJWTSignatureSigningParametersHandler.class, strategy);
+        
+        setErrorEvent(EventIds.INVALID_SEC_CFG);
+        
+        // Create context by default.
+        securityParametersContextLookupStrategy =
+                new ChildContextLookup<>(JWTSecurityParametersContext.class, true).compose(
+                        new InboundMessageContextLookup());
+        
+        noResultIsError = false;
+    }
+    
+    /**
+     * Set lookup strategy for {@link OIDCMetadataContext} for input to resolution.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setClientMetadataContextLookupStrategy(
+            @Nullable final Function<ProfileRequestContext, OIDCMetadataContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        oidcClientMetadataContextLookupStrategy = strategy;
+    }
+    
+    /**
+     * Set lookup strategy for {@link OIDCProviderMetadataContext} for input to resolution.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setProviderMetadataContextLookupStrategy(
+            @Nullable final Function<ProfileRequestContext, OIDCProviderMetadataContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        oidcProviderMetadataContextLookupStrategy = strategy;
+    }
+    
+    /**
+     * Set the strategy used to look up an existing {@link JWTSecurityParametersContext} to copy instead
+     * of actually resolving the parameters to set.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setExistingParametersContextLookupStrategy(
+            @Nullable final Function<ProfileRequestContext,JWTSecurityParametersContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        existingParametersContextLookupStrategy = strategy;
+    }
+    
+    /**
+     * Set the strategy used to look up the {@link JWTSecurityParametersContext} to set the parameters for.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setSecurityParametersContextLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,JWTSecurityParametersContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        securityParametersContextLookupStrategy = Constraint.isNotNull(strategy,
+                "SecurityParametersContext lookup strategy cannot be null");
+    }
+    
+    /**
+     * Set the strategy used to look up a per-request {@link SignatureSigningConfiguration} list.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setConfigurationLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext, List<SignatureSigningConfiguration>> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        configurationLookupStrategy =
+                Constraint.isNotNull(strategy, "SignatureSigningConfiguration lookup strategy cannot be null");
+    }
+    
+    /**
+     * Set the resolver to use for the parameters to store into the context.
+     * 
+     * @param newResolver resolver to use
+     */
+    public void setSignatureSigningParametersResolver(@Nonnull final SignatureSigningParametersResolver newResolver) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        resolver = Constraint.isNotNull(newResolver, "SignatureSigningParametersResolver cannot be null");
+    }
+    
+    /**
+     * Set whether a failure to resolve any parameters should be raised as an exception.
+     * 
+     * <p>
+     * Defaults to false.
+     * </p>
+     * 
+     * @param flag flag to set
+     */
+    public void setNoResultIsError(final boolean flag) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        noResultIsError = flag;
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    protected void doInitialize() throws ComponentInitializationException {
+        super.doInitialize();
+        
+        if (resolver == null) {
+            throw new ComponentInitializationException("SignatureSigningParametersResolver cannot be null");
+        } else if (configurationLookupStrategy == null) {
+            configurationLookupStrategy = new Function<>() {
+                public List<SignatureSigningConfiguration> apply(final ProfileRequestContext input) {
+                    return Collections.singletonList(
+                            SecurityConfigurationSupport.getGlobalSignatureSigningConfiguration());
+                }
+            };
+        }
+
+        final PopulateJWTSignatureSigningParametersHandler delegate = getDelegate();
+        delegate.setNoResultIsError(noResultIsError);
+        delegate.setSignatureSigningParametersResolver(resolver);
+        delegate.setConfigurationLookupStrategy(adapt(configurationLookupStrategy));
+        if (securityParametersContextLookupStrategy != null) {
+            delegate.setSecurityParametersContextLookupStrategy(adapt(securityParametersContextLookupStrategy));
+        }
+        delegate.setExistingParametersContextLookupStrategy(adapt(existingParametersContextLookupStrategy));
+        if (oidcClientMetadataContextLookupStrategy != null) {
+            delegate.setClientMetadataContextLookupStrategy(adapt(oidcClientMetadataContextLookupStrategy));
+        }
+        if (oidcProviderMetadataContextLookupStrategy != null) {
+            delegate.setProviderMetadataContextLookupStrategy(adapt(oidcProviderMetadataContextLookupStrategy));
+        }
+        delegate.initialize();
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+        
+        if (super.doPreExecute(profileRequestContext)) {
+            log.debug("{} Signing enabled", getLogPrefix());
+            return true;
+        }
+        log.debug("{} Signing not enabled", getLogPrefix());
+        return false;
+    }
+
+
+}
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/PopulateJWTSignatureSigningParametersHandler.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/PopulateJWTSignatureSigningParametersHandler.java
new file mode 100644
index 0000000..e3df9da
--- /dev/null
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/PopulateJWTSignatureSigningParametersHandler.java
@@ -0,0 +1,298 @@
+package net.shibboleth.oidc.security.impl;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.messaging.context.navigate.RecursiveTypedParentContextLookup;
+import org.opensaml.messaging.handler.AbstractMessageHandler;
+import org.opensaml.messaging.handler.MessageHandlerException;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.xmlsec.SecurityConfigurationSupport;
+import org.opensaml.xmlsec.SignatureSigningConfiguration;
+import org.opensaml.xmlsec.SignatureSigningParameters;
+import org.opensaml.xmlsec.SignatureSigningParametersResolver;
+import org.opensaml.xmlsec.context.SecurityParametersContext;
+import org.opensaml.xmlsec.criterion.SignatureSigningConfigurationCriterion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
+import net.shibboleth.oidc.metadata.context.OIDCProviderMetadataContext;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
+import net.shibboleth.oidc.security.context.JWTSecurityParametersContext;
+import net.shibboleth.oidc.security.criterion.ClientInformationCriterion;
+import net.shibboleth.oidc.security.criterion.ProviderMetadataCriterion;
+import net.shibboleth.oidc.security.criterion.StaticCredentialCriterion;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+public class PopulateJWTSignatureSigningParametersHandler extends AbstractMessageHandler {
+    
+    /** Class logger. */
+    @Nonnull
+    private final Logger log = LoggerFactory.getLogger(PopulateJWTSignatureSigningParametersHandler.class);
+    
+    /** Strategy used to look up the {@link JWTSecurityParametersContext} to set the parameters for. */
+    @Nonnull private Function<MessageContext, JWTSecurityParametersContext> securityParametersContextLookupStrategy;
+    
+    /** Strategy used to look up an existing {@link JWTSecurityParametersContext} to copy. */
+    @Nullable private Function<MessageContext,JWTSecurityParametersContext> existingParametersContextLookupStrategy;
+    
+    /** Strategy used to look up a per-request {@link SignatureSigningConfiguration} list. */
+    @NonnullAfterInit private Function<MessageContext, List<SignatureSigningConfiguration>> configurationLookupStrategy;
+    
+    /** Strategy used to look up a OIDC client metadata context. */
+    @Nonnull private Function<MessageContext, OIDCMetadataContext> oidcClientMetadataContextLookupStrategy;
+    
+    /** Strategy used to look up a OIDC provider metadata context. */
+    @Nonnull 
+    private Function<MessageContext, OIDCProviderMetadataContext> oidcProviderMetadataContextLookupStrategy;
+    
+    /** Lookup function for relying party context. */
+    @Nonnull private Function<MessageContext, RelyingPartyContext> relyingPartyContextLookupStrategy;
+    
+    /** Resolver for parameters to store into context. */
+    @NonnullAfterInit private SignatureSigningParametersResolver resolver;
+    
+    /** Whether failure to resolve parameters should be raised as an error. */
+    private boolean noResultIsError;
+    
+    /** Constructor.*/
+    public PopulateJWTSignatureSigningParametersHandler() {
+        securityParametersContextLookupStrategy = new ChildContextLookup<>(JWTSecurityParametersContext.class, true);
+        oidcClientMetadataContextLookupStrategy = new ChildContextLookup<>(OIDCMetadataContext.class);
+        oidcProviderMetadataContextLookupStrategy = new ChildContextLookup<>(OIDCProviderMetadataContext.class);
+        relyingPartyContextLookupStrategy =  new ChildContextLookup<>(RelyingPartyContext.class)
+                .compose(new RecursiveTypedParentContextLookup<>(ProfileRequestContext.class));
+    }
+    
+    /**
+     * Set lookup strategy for relying party context.
+     * 
+     * @param strategy  lookup strategy
+     */
+    public void setRelyingPartyContextLookupStrategy(
+            @Nonnull final Function<MessageContext,RelyingPartyContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        
+        relyingPartyContextLookupStrategy =
+                Constraint.isNotNull(strategy, "RelyingPartyContext lookup strategy cannot be null");
+    }
+    
+    /**
+     * Set the strategy used to look up the {@link SecurityParametersContext} to set the parameters for.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setSecurityParametersContextLookupStrategy(
+            @Nonnull final Function<MessageContext, JWTSecurityParametersContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        securityParametersContextLookupStrategy =
+                Constraint.isNotNull(strategy, "JWTSecurityParametersContext lookup strategy cannot be null");
+    }
+    
+    /**
+     * Set lookup strategy for {@link OIDCMetadataContext} for input to resolution.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setClientMetadataContextLookupStrategy(
+            @Nonnull final Function<MessageContext, OIDCMetadataContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        oidcClientMetadataContextLookupStrategy = 
+                Constraint.isNotNull(strategy, "OIDCMetadataContext lookup strategy cannot be null");
+    }
+    
+    /**
+     * Set lookup strategy for {@link OIDCProviderMetadataContext} for input to resolution.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setProviderMetadataContextLookupStrategy(
+            @Nonnull final Function<MessageContext, OIDCProviderMetadataContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        oidcProviderMetadataContextLookupStrategy = 
+                Constraint.isNotNull(strategy, "OIDCProviderMetadataContext lookup strategy cannot be null");
+    }
+    
+    /**
+     * Set the resolver to use for the parameters to store into the context.
+     * 
+     * @param newResolver resolver to use
+     */
+    public void setSignatureSigningParametersResolver(@Nonnull final SignatureSigningParametersResolver newResolver) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        resolver = Constraint.isNotNull(newResolver, "SignatureSigningParametersResolver cannot be null");
+    }
+    
+    /**
+     * Set the strategy used to look up an existing {@link JWTSecurityParametersContext} to copy instead
+     * of actually resolving the parameters to set.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setExistingParametersContextLookupStrategy(
+            @Nullable final Function<MessageContext,JWTSecurityParametersContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        existingParametersContextLookupStrategy = strategy;
+    }
+    
+    /**
+     * Set the strategy used to look up a per-request {@link SignatureSigningConfiguration} list.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setConfigurationLookupStrategy(
+            @Nonnull final Function<MessageContext, List<SignatureSigningConfiguration>> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        configurationLookupStrategy =
+                Constraint.isNotNull(strategy, "SignatureSigningConfiguration lookup strategy cannot be null");
+    }
+    
+    /**
+     * Set whether a failure to resolve any parameters should be raised as an exception.
+     * 
+     * <p>
+     * Defaults to false.
+     * </p>
+     * 
+     * @param flag flag to set
+     */
+    public void setNoResultIsError(final boolean flag) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        noResultIsError = flag;
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    protected void doInitialize() throws ComponentInitializationException {
+        super.doInitialize();
+
+        if (resolver == null) {
+            throw new ComponentInitializationException("SignatureSigningParametersResolver cannot be null");
+        } else if (configurationLookupStrategy == null) {
+            configurationLookupStrategy = new Function<MessageContext, List<SignatureSigningConfiguration>>() {
+                @Override
+                public List<SignatureSigningConfiguration> apply(final MessageContext input) {
+                    return Collections
+                            .singletonList(SecurityConfigurationSupport.getGlobalSignatureSigningConfiguration());
+                }
+            };
+        }
+    }
+    
+    /** {@inheritDoc} */
+    @Override
+    protected boolean doPreInvoke(@Nonnull final MessageContext messageContext) throws MessageHandlerException {
+
+        if (super.doPreInvoke(messageContext)) {
+            log.debug("{} Signing enabled", getLogPrefix());
+            return true;
+        } else {
+            log.debug("{} Signing not enabled", getLogPrefix());
+            return false;
+        }
+    }
+
+    @Override
+    protected void doInvoke(final MessageContext messageContext) throws MessageHandlerException {
+        log.debug("{} Resolving SignatureSigningParameters for request", getLogPrefix());
+
+        final JWTSecurityParametersContext paramsCtx = securityParametersContextLookupStrategy.apply(messageContext);
+        if (paramsCtx == null) {
+            log.debug("{} No JWTSecurityParametersContext returned by lookup strategy", getLogPrefix());
+            throw new MessageHandlerException("No JWTSecurityParametersContext returned by lookup strategy");
+        }
+
+        if (existingParametersContextLookupStrategy != null) {
+            final JWTSecurityParametersContext existingCtx = existingParametersContextLookupStrategy.apply(messageContext);
+            if (existingCtx != null && existingCtx.getSignatureSigningParameters() != null) {
+                log.debug("{} Found existing JWTSecurityParametersContext to copy from", getLogPrefix());
+                paramsCtx.setSignatureSigningParameters(existingCtx.getSignatureSigningParameters());
+                return;
+            }
+        }
+
+        final List<SignatureSigningConfiguration> configs = configurationLookupStrategy.apply(messageContext);
+        if (configs == null || configs.isEmpty()) {
+            log.error("{} No SignatureSigningConfiguration returned by lookup strategy", getLogPrefix());
+            throw new MessageHandlerException("No SignatureSigningConfiguration returned by lookup strategy");
+        }
+
+        final CriteriaSet criteria = new CriteriaSet(new SignatureSigningConfigurationCriterion(configs));
+
+        // Add client metadata criterion
+        final OIDCMetadataContext oidcMetadataCtx = oidcClientMetadataContextLookupStrategy.apply(messageContext);
+        if (oidcMetadataCtx != null && oidcMetadataCtx.getClientInformation() != null) {
+            log.debug("{} Adding OIDC client information to resolution criteria for signing/digest algorithms",
+                    getLogPrefix());
+            criteria.add(new ClientInformationCriterion(oidcMetadataCtx.getClientInformation()));
+        } else {
+            log.debug("{} OIDCMetadataContext is absent", getLogPrefix());
+        }
+        
+        // Add OP metadata criterion
+        final OIDCProviderMetadataContext oidcProviderMetadataCtx = 
+                oidcProviderMetadataContextLookupStrategy.apply(messageContext);
+        if (oidcProviderMetadataCtx != null && oidcProviderMetadataCtx.getProviderInformation() != null) {
+            log.debug("{} Adding OIDC provider information to resolution criteria for signing/digest algorithms",
+                    getLogPrefix());
+            criteria.add(new ProviderMetadataCriterion(oidcProviderMetadataCtx.getProviderInformation()));
+        } else {
+            log.debug("{} OIDCProviderMetadataContext is absent", getLogPrefix());
+        }
+        
+        if (messageContext.getParent() instanceof ProfileRequestContext) {
+            // Add any static credentials from the RP context
+            final RelyingPartyContext rpCtx = 
+                    relyingPartyContextLookupStrategy.apply(messageContext);     
+            if (rpCtx != null && rpCtx.getConfiguration() != null &&
+                    rpCtx.getProfileConfig() instanceof OIDCAuthorizationConfiguration) {
+                final OIDCAuthorizationConfiguration profileConfiguration = 
+                        (OIDCAuthorizationConfiguration) rpCtx.getProfileConfig();
+                
+                if (profileConfiguration != null) {
+                    criteria.add(new StaticCredentialCriterion(
+                            profileConfiguration.getClientCredential((ProfileRequestContext)messageContext.getParent())));
+                } else {
+                    log.trace("{} Profile configuration not available, "
+                            + "shared secret signing credential not present", getLogPrefix());
+                }
+            }
+        }
+
+        try {
+            final SignatureSigningParameters params = resolver.resolveSingle(criteria);
+            if (params == null && noResultIsError) {
+                log.error("Failed to resolve SignatureSigningParameters");
+                throw new MessageHandlerException("Failed to resolve SignatureSigningParameters");
+            }
+            log.debug("{} {} SignatureSigningParameters", getLogPrefix(),
+                    params != null ? "Resolved" : "Failed to resolve");
+            paramsCtx.setSignatureSigningParameters(params);
+        } catch (final ResolverException e) {
+            log.error("{} Error resolving SignatureSigningParameters", getLogPrefix(), e);
+            throw new MessageHandlerException("Error resolving SignatureSigningParameters", e);
+        }
+        
+    }
+
+}
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/PopulateJWTSignatureValidationParameters.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/PopulateJWTSignatureValidationParameters.java
index 13759a0..dd4fa77 100644
--- a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/PopulateJWTSignatureValidationParameters.java
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/impl/PopulateJWTSignatureValidationParameters.java
@@ -22,7 +22,9 @@ import java.util.function.Function;
 
 import javax.annotation.Nonnull;
 
+import org.opensaml.messaging.context.MessageContext;
 import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.messaging.context.navigate.ContextDataLookupFunction;
 import org.opensaml.profile.action.AbstractHandlerDelegatingProfileAction;
 import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
@@ -36,6 +38,7 @@ import net.shibboleth.oidc.security.SignatureValidationConfiguration;
 import net.shibboleth.oidc.security.SignatureValidationParameters;
 import net.shibboleth.oidc.security.SignatureValidationParametersResolver;
 import net.shibboleth.oidc.security.context.JWTSecurityParametersContext;
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 import net.shibboleth.utilities.java.support.component.ComponentSupport;
@@ -67,9 +70,12 @@ public class PopulateJWTSignatureValidationParameters
     
     /**
      * Constructor.
+     * 
+     * @param strategy lookup strategy for message context
      */
-    public PopulateJWTSignatureValidationParameters() {
-        super(PopulateJWTSignatureValidationParametersHandler.class, new InboundMessageContextLookup());
+    public PopulateJWTSignatureValidationParameters(@ParameterName(name="strategy")
+            final ContextDataLookupFunction<ProfileRequestContext, MessageContext> strategy) {
+        super(PopulateJWTSignatureValidationParametersHandler.class, strategy);
         
         // Create context by default.
         securityParametersContextLookupStrategy =
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCSecurityConfiguration.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCSecurityConfiguration.java
index 814eadc..45d1c2b 100644
--- a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCSecurityConfiguration.java
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/config/OIDCSecurityConfiguration.java
@@ -40,6 +40,10 @@ public class OIDCSecurityConfiguration extends SecurityConfiguration {
     /** Configuration used when validating request object information. */
     @Nullable
     private SignatureSigningConfiguration requestObjectSignatureValidationConfig;
+    
+    /** Configuration used when singing request objects. */
+    @Nullable
+    private SignatureSigningConfiguration requestObjectSignatureSigningConfig;
 
     /** Configuration used when validating token endpoint authentication JWT signatures. */
     @Nullable
@@ -66,7 +70,7 @@ public class OIDCSecurityConfiguration extends SecurityConfiguration {
      * 
      * @param config configuration used when decrypting id_tokens, or null
      */
-    public void setIdTokenJwtDecryptionConfig(@Nullable final 
+    public void setIdTokenJwtDecryptionConfiguration(@Nullable final 
             net.shibboleth.oidc.security.DecryptionConfiguration config) {
         idTokenJwtDecryptConfig = config;
     }
@@ -76,7 +80,7 @@ public class OIDCSecurityConfiguration extends SecurityConfiguration {
      * 
      * @return configuration used when decrypting id_tokens, or null
      */
-    @Nullable public net.shibboleth.oidc.security.DecryptionConfiguration getIdtokenJwtDecryptionConfig() {
+    @Nullable public net.shibboleth.oidc.security.DecryptionConfiguration getIdtokenJwtDecryptionConfiguration() {
         return idTokenJwtDecryptConfig;
     }
     
@@ -85,7 +89,7 @@ public class OIDCSecurityConfiguration extends SecurityConfiguration {
      * 
      * @param config configuration used when decrypting UserInfo JWTs, or null
      */
-    public void setUserInfoJwtDecryptionConfig(@Nullable final 
+    public void setUserInfoJwtDecryptionConfiguration(@Nullable final 
             net.shibboleth.oidc.security.DecryptionConfiguration config) {
         userInfoJwtDecryptConfig = config;
     }
@@ -95,7 +99,7 @@ public class OIDCSecurityConfiguration extends SecurityConfiguration {
      * 
      * @return configuration used when decrypting UserInfo JWTs, or null
      */
-    @Nullable public net.shibboleth.oidc.security.DecryptionConfiguration getUserInfoJwtDecryptionConfig() {
+    @Nullable public net.shibboleth.oidc.security.DecryptionConfiguration getUserInfoJwtDecryptionConfiguration() {
         return userInfoJwtDecryptConfig;
     }
 
@@ -118,6 +122,25 @@ public class OIDCSecurityConfiguration extends SecurityConfiguration {
         requestObjectDecryptConfig = config;
     }
 
+    /**
+     * Get the configuration used when signing request object information.
+     * 
+     * @return configuration used when signing request object information, or null
+     */
+    @Nullable
+    public SignatureSigningConfiguration getRequestObjectSignatureSigningConfiguration() {
+        return requestObjectSignatureSigningConfig;
+    }
+
+    /**
+     * Set the configuration used when signing request object information.
+     * 
+     * @param config used when signing request object information, or null
+     */
+    public void setRequestObjectSignatureSigningConfiguration(@Nullable final SignatureSigningConfiguration config) {
+        requestObjectSignatureSigningConfig = config;
+    }
+    
     /**
      * Get the configuration used when validating request object information.
      * 
@@ -163,7 +186,8 @@ public class OIDCSecurityConfiguration extends SecurityConfiguration {
      * @return configuration used when validating id_token JWT signatures, or null
      */
     @Nullable
-    public net.shibboleth.oidc.security.SignatureValidationConfiguration<SignedJWT> getIdTokenJwtSignatureValidationConfig() {
+    public net.shibboleth.oidc.security.SignatureValidationConfiguration<SignedJWT> 
+            getIdTokenJwtSignatureValidationConfiguration() {
         return idTokenJwtSignatureValidationConfig;
     }
 
@@ -172,7 +196,7 @@ public class OIDCSecurityConfiguration extends SecurityConfiguration {
      * 
      * @param config configuration used when validating id_token JWT signatures, or null
      */
-    public void setIdTokenJwtSignatureValidationConfig(
+    public void setIdTokenJwtSignatureValidationConfiguration(
             @Nullable final net.shibboleth.oidc.security.SignatureValidationConfiguration<SignedJWT> config) {
         idTokenJwtSignatureValidationConfig = config;
     }
@@ -183,7 +207,8 @@ public class OIDCSecurityConfiguration extends SecurityConfiguration {
      * @return configuration used when validating id_token JWT signatures, or null
      */
     @Nullable
-    public net.shibboleth.oidc.security.SignatureValidationConfiguration<SignedJWT> getUserInfoTokenJwtSignatureValidationConfig() {
+    public net.shibboleth.oidc.security.SignatureValidationConfiguration<SignedJWT> 
+            getUserInfoTokenJwtSignatureValidationConfiguration() {
         return userInfoTokenJwtSignatureValidationConfig;
     }
 
@@ -192,7 +217,7 @@ public class OIDCSecurityConfiguration extends SecurityConfiguration {
      * 
      * @param config configuration used when validating id_token JWT signatures, or null
      */
-    public void setUserInfoTokenJwtSignatureValidationConfig(
+    public void setUserInfoTokenJwtSignatureValidationConfiguration(
             @Nullable final net.shibboleth.oidc.security.SignatureValidationConfiguration<SignedJWT> config) {
         userInfoTokenJwtSignatureValidationConfig = config;
     }
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OAuthAuthorizationRequest.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OAuthAuthorizationRequest.java
index 9ef16de..02b79bc 100644
--- a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OAuthAuthorizationRequest.java
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OAuthAuthorizationRequest.java
@@ -94,6 +94,13 @@ public class OAuthAuthorizationRequest {
     /** The response mode. Optional. */
     @Nullable private ResponseMode responseMode;
     
+    /** 
+     * The default response mode for the given response_type. Can be used
+     * to determine if the response_mode should be included in an authentication
+     * request. 
+     */
+    @Nullable private ResponseMode defaultResponseMode;
+    
     //TODO there are a few others.
     
     /**
@@ -108,6 +115,24 @@ public class OAuthAuthorizationRequest {
         scope = new Scope();
         
     }
+    
+    /**
+     * Set the default response_mode for the given response_type. 
+     * 
+     * @param mode the default response_mode for the given response_type
+     */
+    public void setDefaultResponseMode(@Nullable final ResponseMode mode) {
+        defaultResponseMode = mode;
+    }
+    
+    /**
+     * Get the response_mode to use with this authentication request.
+     * 
+     * @return the default response_mode
+     */
+    @Nullable public ResponseMode getDefaultResponseMode() {
+        return defaultResponseMode;
+    }
 
     /**
      * Get the client ID. 
@@ -301,9 +326,11 @@ public class OAuthAuthorizationRequest {
     }
 
     /**
-     * Set the response mode.
+     * Set the response mode to be used with the ongoing authentication request.
+     * This can be {@literal null} if the default response_mode is
+     * to be used by the OP.
      * 
-     * @param mode The responseMode to set.
+     * @param mode the response mode. {@literal null} if default mode is to be used.
      */
     public void setResponseMode(@Nullable final ResponseMode mode) {
         responseMode = mode;

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


More information about the commits mailing list