[java-oidc-common] branch main updated: Move signing parameter resolver from RP to commons

Phil Smart philip.smart at jisc.ac.uk
Wed Apr 26 12:46:31 UTC 2023


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

philsmart 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=5064fc2cae1bfa008cd93a596ed52782e44e8d04

The following commit(s) were added to refs/heads/main by this push:
     new 5064fc2  Move signing parameter resolver from RP to commons
5064fc2 is described below

commit 5064fc2cae1bfa008cd93a596ed52782e44e8d04
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Wed Apr 26 13:46:05 2023 +0100

    Move signing parameter resolver from RP to commons
    
         - Supports pulling a signing credential from the client_secret in the profile configuration
---
 .../RelyingPartySigningParametersResolver.java     | 166 +++++++++++++++++++++
 .../impl/HTTPPostAuthnResponseDecoder.java         |   2 -
 .../impl/HTTPRedirectAuthnResponseDecoder.java     |   1 -
 3 files changed, 166 insertions(+), 3 deletions(-)

diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/RelyingPartySigningParametersResolver.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/RelyingPartySigningParametersResolver.java
new file mode 100644
index 0000000..572b948
--- /dev/null
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jose/impl/RelyingPartySigningParametersResolver.java
@@ -0,0 +1,166 @@
+/*
+ * 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.jose.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.security.credential.Credential;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.nimbusds.jose.Algorithm;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+
+import net.shibboleth.oidc.security.credential.ClientSecretCredential;
+import net.shibboleth.oidc.security.jose.SignatureSigningParameters;
+import net.shibboleth.oidc.security.jose.criterion.ClientSecretCredentialCriterion;
+import net.shibboleth.oidc.security.jose.criterion.ProviderMetadataCriterion;
+import net.shibboleth.oidc.security.jose.impl.BasicSignatureSigningParametersResolver;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.logic.FunctionSupport;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+
+/**
+ * A specialization of {@link BasicSignatureSigningParametersResolver} which supports selecting signing credentials
+ * from client_secret credential criterion (e.g. from the relying party configuration) in addition to the configured 
+ * signing credentials inside the signing configuration (determined by the superclass). 
+ * 
+ * <p>The OpenID Providers's metadata is also used to filter for those algorithms supported by the OP in addition to
+ * those supported by the security configuration.</p>
+ * 
+ *  * <p>
+ * In addition to the {@link net.shibboleth.utilities.java.support.resolver.Criterion} inputs documented in
+ * {@link BasicSignatureSigningParametersResolver}, the following inputs are also supported:
+ * </p>
+ * <ul>
+ * <li>{@link ClientSecretCredentialCriterion} - optional</li>
+ * <li>{@link ProviderMetadataCriterion} - required</li>
+ * </ul>
+ */
+public class RelyingPartySigningParametersResolver extends BasicSignatureSigningParametersResolver {
+    
+    /** Logger. */
+    @Nonnull
+    private final Logger log = LoggerFactory.getLogger(RelyingPartySigningParametersResolver.class);
+    
+    /** 
+     * A strategy to pull out the correct set of supported algorithms from the {@link OIDCProviderMetadata}.
+     * By default returns {@literal null}, signalling 'do not filter'.
+     */
+    @Nonnull private Function<OIDCProviderMetadata, List<String>> providerMetadataAlgorithmLookupStrategy;
+    
+    /** Constructor.*/
+    public RelyingPartySigningParametersResolver() {
+        // Always provide a strategy to avoid NPE, but default returns null e.g. do not filter.
+        providerMetadataAlgorithmLookupStrategy = FunctionSupport.constant(null);
+    }
+    
+    /**
+     * Set the strategy used to locate the supported signing algorithms from the OP's metadata for this
+     * resolver instance. For example, id_token or request object signing algorithms.
+     *  
+     * @param strategy the strategy
+     */
+    public void setProviderMetadataAlgorithmLookupStrategy(
+            @Nonnull final Function<OIDCProviderMetadata, List<String>> strategy) {
+        providerMetadataAlgorithmLookupStrategy = 
+                Constraint.isNotNull(strategy, "ProviderMetadataAlgorithmLookupStrategy can not be null");
+    }
+    
+ // Checkstyle: CyclomaticComplexity|ReturnCount OFF
+    @Override
+    protected void resolveAndPopulateCredentialAndSignatureAlgorithm(
+            @Nonnull final SignatureSigningParameters params, 
+            @Nonnull final CriteriaSet criteria, @Nonnull final Predicate<String> includeExcludePredicate) {
+        
+        final List<Credential> allCredentials = new ArrayList<>();
+        
+        // Add any static credentials from the criteria
+        if (criteria.contains(ClientSecretCredentialCriterion.class)) {
+            final ClientSecretCredential staticCred = 
+                    criteria.get(ClientSecretCredentialCriterion.class).getCredential();
+            log.trace("Client secret signing credential found in criterion");
+            // Extract a key suitable for creating and validating MACs
+            allCredentials.add(staticCred.toSigningCredential());
+        }
+        
+        // Add any credentials from the configuration
+        allCredentials.addAll(getEffectiveSigningCredentials(criteria));
+        
+        // Get effective signature algorithms from configuration and include/exclude predicate
+        final List<String> algorithms = getEffectiveSignatureAlgorithms(criteria, includeExcludePredicate);      
+        log.debug("Resolved effective signature algorithms from config: '{}'", algorithms);
+        
+        // Filter by those supported by the upstream OP
+        final List<String> supportedAlgorithms = filterForProviderSupportedAlgorithms(criteria, algorithms);
+        log.trace("Resolved effective signature algorithms: {}", supportedAlgorithms);
+        
+        findCompatibleAlgorithmAndCredential(supportedAlgorithms, allCredentials, params);
+
+    }  
+
+    /**
+     * Convert the algorithms represented as strings, into Nimbus {@link Algorithm}s for later comparison.
+     * 
+     * @param algos the algorithms to convert
+     * 
+     * @return the converted algorithms
+     */
+    @Nonnull private List<JWSAlgorithm> convertSupportAlgorithmsToJwkAlgorithms(@Nonnull final List<String> algos) {
+        return algos.stream().map(JWSAlgorithm::parse).collect(Collectors.toList());
+    }
+
+    /**
+     * Filter the set of algorithms against the set supported by the OpenID Provider.
+     * Always returns a new list reference. The ordering of the input algorithms should be preserved. 
+     * 
+     * @param criteria the criteria to extract the OP's metadata from to check supported algorithms.
+     * @param algorithms the current set of supported algorithms
+     * 
+     * @return the current set of supported algorithms filtered by those also supported by the OP.
+     */
+    private List<String> filterForProviderSupportedAlgorithms(
+            @Nonnull final CriteriaSet criteria, @Nonnull final List<String> algorithms) {
+
+        if (criteria.contains(ProviderMetadataCriterion.class)) {
+            final OIDCProviderMetadata metadata = criteria.get(ProviderMetadataCriterion.class).getMetadata();
+            
+            final List<String> opSupportedAlgNames = providerMetadataAlgorithmLookupStrategy.apply(metadata);
+            log.trace("Provider metadata supports the following signature algorithms '{}'",opSupportedAlgNames);
+            
+            if (opSupportedAlgNames == null) {
+                log.trace("Lookup strategy could not determine provider supported algorithms from metadata, "
+                        + "no further filtering performed");
+                return List.copyOf(algorithms);
+            }
+            return algorithms.stream().filter(opSupportedAlgNames::contains).collect(Collectors.toList());
+            
+        } else {
+            log.debug("No provider metadata criterion, unable to filter for provider supported algorithms");
+            return List.copyOf(algorithms);
+        }
+    }
+
+}
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPPostAuthnResponseDecoder.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPPostAuthnResponseDecoder.java
index 51a1ab0..6fc0e73 100644
--- a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPPostAuthnResponseDecoder.java
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPPostAuthnResponseDecoder.java
@@ -40,8 +40,6 @@ import net.shibboleth.oidc.profile.decoding.OIDCMessageDecoder;
  * A {@link MessageDecoder message decoder} that decodes an incoming {@link AuthenticationResponse}
  * when using a form_post response_type.
  */
-//TODO this is identical to the HTTPRedirectAuthnDecoder because it uses the Nimbus parser.
-// do we leave as a placeholder for when we create our own decoders?
 public class HTTPPostAuthnResponseDecoder extends AbstractHttpServletRequestMessageDecoder
                     implements OIDCMessageDecoder {
     
diff --git a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPRedirectAuthnResponseDecoder.java b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPRedirectAuthnResponseDecoder.java
index 24f68e4..aa6c6ba 100644
--- a/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPRedirectAuthnResponseDecoder.java
+++ b/oidc-common-profile-impl/src/main/java/net/shibboleth/oidc/profile/decoding/impl/HTTPRedirectAuthnResponseDecoder.java
@@ -41,7 +41,6 @@ import net.shibboleth.oidc.profile.decoding.OIDCMessageDecoder;
  * A {@link MessageDecoder message decoder} that decodes an incoming {@link AuthenticationResponse}
  * when using a query response_mode.
  */
-//TODO this is identical to the HTTPPostAuthnDecoder because it uses the Nimbus parser.
 public class HTTPRedirectAuthnResponseDecoder extends AbstractHttpServletRequestMessageDecoder 
                 implements OIDCMessageDecoder {
     

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


More information about the commits mailing list