[java-idp-plugin-oidc-rp] branch main updated: Cleanup flow beans, add extra JWT validation

Phil Smart philip.smart at jisc.ac.uk
Fri Dec 16 13:55:50 UTC 2022


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

philsmart pushed a commit to branch main
in repository java-idp-plugin-oidc-rp.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-oidc-rp.git;a=commit;h=2c797c91fd81ef7a5659a0238cb97643f5f063d5

The following commit(s) were added to refs/heads/main by this push:
     new 2c797c9  Cleanup flow beans, add extra JWT validation
2c797c9 is described below

commit 2c797c91fd81ef7a5659a0238cb97643f5f063d5
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Dec 16 13:55:47 2022 +0000

    Cleanup flow beans, add extra JWT validation
    
     - ACR and auth_time validator improvements
     - Some JavaDoc fixes
     - Logging improvements
---
 .../RequiresSignatureVerificationPredicate.java    |   7 +-
 .../navigate/ExtraAudiencesLookupStrategy.java     |  54 ++++++
 .../authn/oidc/rp/context/OAuth2ClientContext.java |   2 +-
 .../rp/impl/InitializeOAuth2ClientContext.java     |   6 +-
 .../impl/ValidateAuthenticationResponseResult.java |  22 ++-
 .../META-INF/net.shibboleth.idp/postconfig.xml     |  29 ++++
 .../oidc-relying-party-authn-beans.xml             | 182 ++++++++++-----------
 7 files changed, 195 insertions(+), 107 deletions(-)

diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/RequiresSignatureVerificationPredicate.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/RequiresSignatureVerificationPredicate.java
index 226b666..2ed85a8 100644
--- a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/RequiresSignatureVerificationPredicate.java
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/RequiresSignatureVerificationPredicate.java
@@ -31,7 +31,7 @@ import net.shibboleth.utilities.java.support.annotation.ParameterName;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 
 /**
- * Is successful TLS credential verficiation enough to validate the JWT in question? Defaults to true — 
+ * Is successful TLS credential verification enough to validate the JWT in question? Defaults to true — 
  * signature verification is required.
  */
 public class RequiresSignatureVerificationPredicate implements Predicate<MessageContext> {
@@ -56,7 +56,8 @@ public class RequiresSignatureVerificationPredicate implements Predicate<Message
      *
      * @param strategy the strategy used to locate the {@link AbstractAuthenticatableOIDCContext} to test
      */
-    public RequiresSignatureVerificationPredicate(@Nonnull @ParameterName(name="authenticatableOIDCContextLookupStrategy") 
+    public RequiresSignatureVerificationPredicate(
+            @Nonnull @ParameterName(name="authenticatableOIDCContextLookupStrategy") 
             final Function<MessageContext, AbstractAuthenticatableOIDCContext> strategy) {
         super();
         authenticatableOIDCContextLookupStrategy = Constraint.isNotNull(strategy,
@@ -81,7 +82,7 @@ public class RequiresSignatureVerificationPredicate implements Predicate<Message
         
         if (tlsServerValidationOnly && authContext.isAuthenticated()) {
             // No further validation required.
-            log.debug("TLS server validation was successful and sufficient, no further signature processing performed");
+            log.debug("TLS server validation was successful and sufficient, no further signature processing required");
             return false;
         }       
         
diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/ExtraAudiencesLookupStrategy.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/ExtraAudiencesLookupStrategy.java
new file mode 100644
index 0000000..2248aca
--- /dev/null
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/ExtraAudiencesLookupStrategy.java
@@ -0,0 +1,54 @@
+
+package net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+
+import net.shibboleth.idp.profile.config.ProfileConfiguration;
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+/**
+ * Locate additional accepted audiences from the additional audiences for ID Token profile config value.
+ */
+public class ExtraAudiencesLookupStrategy implements BiFunction<ProfileRequestContext, JWTClaimsSet, Set<String>> {
+    
+    /** Lookup function for relying party context. */
+    @Nonnull private final Function<ProfileRequestContext,RelyingPartyContext> relyingPartyContextLookupStrategy;
+    
+    /**
+     * 
+     * Constructor.
+     *
+     * @param strategy the strategy used to lookup a relying party context
+     */
+    public ExtraAudiencesLookupStrategy(@ParameterName(name = "relyingPartyContextLookupStrategy")
+            @Nonnull final Function<ProfileRequestContext,RelyingPartyContext> strategy) {
+        relyingPartyContextLookupStrategy =
+                Constraint.isNotNull(strategy, "RelyingPartyContext lookup strategy cannot be null");
+    }
+
+    @Override
+    public Set<String> apply(final ProfileRequestContext prc, final JWTClaimsSet claims) {
+        
+        final RelyingPartyContext rpc = relyingPartyContextLookupStrategy.apply(prc);
+        if (rpc != null) {
+            final ProfileConfiguration pc = rpc.getProfileConfig();
+            if (pc instanceof OIDCAuthorizationConfiguration) {
+                return ((OIDCAuthorizationConfiguration)pc).getAdditionalAudiencesForIdToken(prc);
+            }
+        }
+        return Collections.emptySet();
+    }
+
+}
diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OAuth2ClientContext.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OAuth2ClientContext.java
index ed8c048..61c14f2 100644
--- a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OAuth2ClientContext.java
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OAuth2ClientContext.java
@@ -29,7 +29,7 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
 
 /**
  * A context to store information pertaining to the OAuth2 client (Relying Party) to use in communication
- * with a OpenId Connect Provider.
+ * with a OpenID Provider.
  * 
  * <p>Typically a subcontext under {@link OIDCPeerEntityContext}, as it relates to the client
  * associated pairwise with the downstream OP peer.</p>
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/InitializeOAuth2ClientContext.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/InitializeOAuth2ClientContext.java
index cf3fde2..30923db 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/InitializeOAuth2ClientContext.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/InitializeOAuth2ClientContext.java
@@ -44,13 +44,13 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
 
 /**
- * An {@link AbstractProfileAction action} that resolves the client identifier for the chosen 
- * upstream provider (issuer). 
+ * An {@link AbstractProfileAction action} that resolves the client identifier and redirect URI for the chosen 
+ * provider (issuer). 
  * 
  * @event {@link org.opensaml.profile.action.EventIds#PROCEED_EVENT_ID}
  * @event {@link IdPEventIds#INVALID_PROFILE_CONFIG}
  * @event {@link EventIds#INVALID_PROFILE_CTX}
- * @post Add the clientId to the {@link OAuth2ClientContext}
+ * @post Add the clientId and redirect URI to the {@link OAuth2ClientContext}
  */
 public class InitializeOAuth2ClientContext extends AbstractProfileAction {
 
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ValidateAuthenticationResponseResult.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ValidateAuthenticationResponseResult.java
index 2e3becd..82a967f 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ValidateAuthenticationResponseResult.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ValidateAuthenticationResponseResult.java
@@ -27,6 +27,7 @@ import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.nimbusds.oauth2.sdk.ErrorResponse;
 import com.nimbusds.openid.connect.sdk.AuthenticationErrorResponse;
 import com.nimbusds.openid.connect.sdk.AuthenticationResponse;
 
@@ -76,7 +77,7 @@ public class ValidateAuthenticationResponseResult extends AbstractAuthentication
         if (!authenticationResponse.indicatesSuccess()) {
             final AuthenticationErrorResponse error = authenticationResponse.toErrorResponse();
             log.error("{} OIDC Authentication Response contained an error from upstream OP '{}' : {}", 
-                    getLogPrefix(), authenticationContext.getAuthenticatingAuthority(), error.getErrorObject());
+                    getLogPrefix(), authenticationContext.getAuthenticatingAuthority(),buildErrorResponseString(error));
             // TODO: maybe more specific error, and or an error branch in the flow e.g. maybe a UI element?
             ActionSupport.buildEvent(profileRequestContext, EventIds.MESSAGE_PROC_ERROR);
         } else {
@@ -85,4 +86,23 @@ public class ValidateAuthenticationResponseResult extends AbstractAuthentication
        
     }
     
+    /**
+     * Build an error response string from the {@link ErrorResponse} object.
+     * 
+     * @param error the error
+     * 
+     * @return a string representation of the error
+     */
+    private String buildErrorResponseString(@Nonnull final AuthenticationErrorResponse error) {
+        final StringBuilder builder = new StringBuilder();
+        if (error.getErrorObject() != null) {
+            builder.append("Code -> '").append(error.getErrorObject().getCode()).append("'");
+            builder.append(", ");
+            builder.append("Description -> '").append(error.getErrorObject().getDescription()).append("'");
+        } else {
+            builder.append("Unknown error response");
+        }
+        return builder.toString();
+    }
+    
 }
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index 3e7dff0..288d9f8 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -135,12 +135,41 @@
         class="org.opensaml.messaging.context.navigate.MessageLookup"
         c:type="#{ T(net.shibboleth.oidc.profile.core.OIDCAuthenticationRequest) }" />
         
+   <bean id="shibboleth.ChildLookup.MessageLookup.Outbound.OIDCAuthenticationRequest" 
+            parent="shibboleth.Functions.Compose">
+        <constructor-arg name="g">
+            <ref bean="shibboleth.MessageLookup.oidc.rp.OIDCAuthenticationRequest" />
+        </constructor-arg>
+        <constructor-arg name="f">
+            <ref bean="shibboleth.MessageContextLookup.Outbound" />
+        </constructor-arg>
+    </bean>
+        
     <bean id="shibboleth.MessageLookup.oidc.rp.AuthenticationResponse"
         class="org.opensaml.messaging.context.navigate.MessageLookup"
         c:type="#{ T(com.nimbusds.openid.connect.sdk.AuthenticationResponse) }" />
         
     <bean id="shibboleth.ChildLookup.AccessTokenResponseFromInbound" parent="shibboleth.Functions.Compose"
         c:g-ref="shibboleth.ChildLookup.AccessTokenResponseContext" c:f-ref="shibboleth.MessageContextLookup.Inbound" />
+        
+    <bean id="shibboleth.ChildLookup.OutboundOIDCMetadataContextLookup" parent="shibboleth.Functions.Compose">
+        <constructor-arg name="g">
+            <bean class="org.opensaml.messaging.context.navigate.ChildContextLookup"
+                c:type="#{ T(net.shibboleth.oidc.metadata.context.OIDCProviderMetadataContext) }" />
+        </constructor-arg>
+        <constructor-arg name="f">
+            <bean parent="shibboleth.Functions.Compose">
+                <constructor-arg name="g">
+                    <bean class="org.opensaml.messaging.context.navigate.ChildContextLookup"
+                        c:type="#{ T(net.shibboleth.idp.plugin.authn.oidc.rp.context.OIDCPeerEntityContext) }" />
+                </constructor-arg>
+                <constructor-arg name="f">
+                    <bean class="org.opensaml.messaging.context.navigate.MessageContextLookup"
+                        c:direction="OUTBOUND" />
+                </constructor-arg>
+            </bean>
+        </constructor-arg>
+    </bean>
     
     <!-- Aliases to use in the flow config -->
     <alias name="shibboleth.ChildLookup.Proxy.MessageContextLookup.Inbound" alias="InboundMessageContextFromRootPRC"/>
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
index 45fda2e..7669289 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
@@ -17,12 +17,13 @@
 
 
     <!-- Initial discovery step -->
+    
     <bean id="PropertyDrivenDiscovery" parent="shibboleth.Functions.Constant"
         c:target="#{'%{idp.authn.oidc.rp.provider.proxyIssuer:}'.trim()}" />
 
 
     <!-- Parent beans for indirecting into nested PRC. -->
-
+    
     <bean id="NestedWebFlowMessageHandlerAdaptor" abstract="true"
         class="net.shibboleth.idp.profile.impl.WebFlowMessageHandlerAdaptor" scope="prototype"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext" />
@@ -140,8 +141,7 @@
         <property name="errorEvent">
             <util:constant static-field="org.opensaml.profile.action.EventIds.INVALID_MESSAGE" />
         </property>
-    </bean>
-    
+    </bean>    
         
     <bean id="PostRequestPopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
@@ -154,18 +154,12 @@
         p:useDefaultTimeZone="#{getObject('shibboleth.AuditDefaultTimeZone') ?: false}"
         p:httpServletRequest-ref="shibboleth.authn.oidc.rp.internal.HttpServletRequest" />
 
-
-    <!-- Build RequestObject if required -->
     <bean id="RequestObjectRequiredAndSupportedPredicate"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.messaging.context.logic.RequestObjectRequiredAndSupported" />
 
-
-    <bean id="SignRequestObjectProxyCondition"
+    <bean id="shibboleth.authn.oidc.rp.SignRequestObjectProxyCondition"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.SignRequestObjectPredicate"
         p:relyingPartyContextLookupStrategy-ref="shibboleth.ChildLookup.Proxy.RelyingPartyContext" />
-    <bean id="SignRequestObjectCondition"
-        class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.SignRequestObjectPredicate"
-        p:relyingPartyContextLookupStrategy-ref="shibboleth.ChildLookup.RelyingParty" />
 
     <bean id="EncryptRequestObjectCondition"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.EncryptRequestObjectPredicate"
@@ -177,7 +171,7 @@
         p:configurationLookupStrategy-ref="RequestObjectSignatureSigningConfigurationLookup"
         p:providerMetadataContextLookupStrategy-ref="shibboleth.ChildLookup.OIDCProviderMetadataContextFromOutbound"
         p:signatureSigningParametersResolver-ref="shibboleth.authn.oidc.rp.RequestObjectSignatureSigningParametersResolver"
-        p:activationCondition-ref="SignRequestObjectProxyCondition" />
+        p:activationCondition-ref="shibboleth.authn.oidc.rp.SignRequestObjectProxyCondition" />
 
     <bean id="shibboleth.authn.oidc.rp.RequestObjectSignatureSigningParametersResolver"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.RelyingPartyProxySigningParametersResolver"
@@ -190,7 +184,6 @@
         class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.RequestObjectSignatureSigningConfigurationLookupFunction"
         p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver" />
 
-
     <bean id="PopulateRequestObjectEncryptionParameters"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.PopulateJWTEncryptionParameters" scope="prototype"
         p:forFriendlyName="Request Object"
@@ -232,7 +225,11 @@
         scope="prototype" p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup"
         p:claimsSetIsValidPredicate="#{getObject('shibboleth.authn.oidc.rp.RequestObjectClaimsSetIsValidPredicate')}"
-        p:requestObjectToBeSignedPredicate-ref="SignRequestObjectCondition" />
+        p:requestObjectToBeSignedPredicate-ref="shibboleth.authn.oidc.rp.SignRequestObjectCondition" />
+        
+   <bean id="shibboleth.authn.oidc.rp.SignRequestObjectCondition"
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.SignRequestObjectPredicate"
+        p:relyingPartyContextLookupStrategy-ref="shibboleth.ChildLookup.RelyingParty" />
 
 
     <!-- Message Encoder factory is a prototype to allow reuse of the encoders -->
@@ -466,7 +463,7 @@
         c:executionDirection="INBOUND">
         <constructor-arg>
             <bean class="org.opensaml.messaging.handler.impl.BasicMessageHandlerChain"
-                p:activationCondition-ref="IDTokenRequiresSignatureVerificationCondition">
+                p:activationCondition-ref="shibboleth.authn.oidc.rp.IDTokenRequiresSignatureVerificationCondition">
                 <property name="handlers">
                     <list>
                     
@@ -482,7 +479,7 @@
                         
                         <bean
                             class="net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl.OIDCProviderMetadataLookupHandler"
-                            scope="prototype" p:copyContextStrategy-ref="OutboundOIDCMetadataContextLookup"
+                            scope="prototype" p:copyContextStrategy-ref="shibboleth.ChildLookup.OutboundOIDCMetadataContextLookup"
                             p:providerMetadataResolver-ref="shibboleth.authn.oidc.rp.ProviderMetadataResolver" />
                             
                         <bean class="net.shibboleth.oidc.security.impl.JWTMessageSignatureSecurityHandler"
@@ -503,42 +500,16 @@
                 </property>
             </bean>
         </constructor-arg>
+        <property name="errorEvent">
+            <util:constant static-field="org.opensaml.profile.action.EventIds.INVALID_MESSAGE" />
+        </property>
     </bean>
     
-    <bean id="IDTokenRequiresSignatureVerificationCondition" scope="prototype" 
+    <bean id="shibboleth.authn.oidc.rp.IDTokenRequiresSignatureVerificationCondition" scope="prototype" 
         class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.RequiresSignatureVerificationPredicate"
         p:tlsServerValidationOnly="%{idp.authn.oidc.rp.client.idtoken.tlsServerValidationOnly:false}"
         c:authenticatableOIDCContextLookupStrategy-ref="shibboleth.ChildLookup.AccessTokenResponseContext"/>
 
-    <bean id="OutboundOIDCMetadataContextLookup" parent="shibboleth.Functions.Compose">
-        <constructor-arg name="g">
-            <bean class="org.opensaml.messaging.context.navigate.ChildContextLookup"
-                c:type="#{ T(net.shibboleth.oidc.metadata.context.OIDCProviderMetadataContext) }" />
-        </constructor-arg>
-        <constructor-arg name="f">
-            <bean parent="shibboleth.Functions.Compose">
-                <constructor-arg name="g">
-                    <bean class="org.opensaml.messaging.context.navigate.ChildContextLookup"
-                        c:type="#{ T(net.shibboleth.idp.plugin.authn.oidc.rp.context.OIDCPeerEntityContext) }" />
-                </constructor-arg>
-                <constructor-arg name="f">
-                    <bean class="org.opensaml.messaging.context.navigate.MessageContextLookup"
-                        c:direction="OUTBOUND" />
-                </constructor-arg>
-            </bean>
-        </constructor-arg>
-    </bean>
-
-    <!-- these are part of the global system just tmp for now -->
-    <bean id="shibboleth.SignatureValidationConfigurationLookup" lazy-init="true"
-        class="net.shibboleth.idp.profile.config.navigate.SignatureValidationConfigurationLookupFunction"
-        p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver" />
-    <bean id="shibboleth.SignatureValidationParametersResolver"
-        class="org.opensaml.xmlsec.impl.BasicSignatureValidationParametersResolver" />
-
-    <!-- Default id_token and some UserInfo JWT validation wiring. -->
-
-    <!-- No default cleanup, maybe could be to remove nonce etc. -->
     <bean id="ValidateIDTokenClaims" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.ValidateTokenClaims"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
@@ -546,17 +517,28 @@
         p:cleanupHook="#{getObject('shibboleth.authn.oidc.rp.idtoken.jwt.claims.CleanUpHook') 
            ?: getObject('DefaultCleanupHook')}"
         p:claimsValidator="#{getObject('shibboleth.authn.oidc.rp.idtoken.IDTokenClaimsValidator') 
-           ?: getObject('DefaultIDTokenClaimsValidator')}"
+           ?: getObject('shibboleth.authn.oidc.rp.idtoken.DefaultIDTokenClaimsValidator')}"
         p:jwtLookupStrategy="#{getObject('shibboleth.authn.oidc.rp.idtoken.IDTokenLookupStrategy') 
            ?: getObject('shibboleth.authn.oidc.rp.DefaultIDTokenLookupStrategy')}" />
-
-    <bean id="DefaultIDTokenClaimsValidator"
+           
+    <bean id="shibboleth.authn.oidc.rp.idtoken.DefaultIDTokenClaimsValidator"
         class="net.shibboleth.oidc.security.jwt.claims.impl.ChainingJWTClaimsValidator"
         p:claimValidators-ref="IDTokenClaimsValidators" />
-
-    <bean id="OIDCProviderMetadataContextChildLookup"
-        class="org.opensaml.messaging.context.navigate.ChildContextLookup"
-        c:type="#{ T(net.shibboleth.oidc.metadata.context.OIDCProviderMetadataContext) }" />
+    
+    <util:list id="IDTokenClaimsValidators" value-type="net.shibboleth.oidc.jwt.claims.ClaimsValidator">
+        <ref bean="IDTokenRequiredClaimsValidator" />
+        <ref bean="IssuerClaimsValidator" />
+        <ref bean="AudienceClaimsValidator" />
+        <ref bean="AzpClaimRequiredValidator" />
+        <ref bean="AzpClaimsValidator" />
+        <ref bean="ExpiryClaimsValidator" />
+        <ref bean="IssuedAtClaimsValidator" />
+        <ref bean="NotBeforeClaimsValidator" />
+        <ref bean="NonceClaimValidator" />
+        <ref bean="AtHashValidator"/>
+        <ref bean="AuthenticationTimeClaimValidator"/>
+        <ref bean="ACRClaimValidator"/>
+    </util:list>
 
     <bean id="IDTokenRequiredClaimsValidator"
         class="net.shibboleth.oidc.security.jwt.claims.impl.RequiredClaimsValidator"
@@ -599,7 +581,6 @@
         </property>
     </bean>
 
-    <!-- TODO, seems like this could be done in XML somehow -->
     <bean id="ManyValuesPredicate"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.security.impl.ManyValuesIntegerComparisonPredicate" />
 
@@ -620,15 +601,18 @@
         class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.OIDCProviderMetadataFromOuboundPeerLookupStrategy" />
 
     <bean id="AudienceClaimsValidator" class="net.shibboleth.oidc.security.jwt.claims.impl.AudienceClaimsValidator"
-        p:audienceLookupStrategy-ref="ClientIDFromOAuth2ClientContextFunction" />
-
-
+        p:audienceLookupStrategy-ref="ClientIDFromOAuth2ClientContextFunction"
+        p:extraAudienceValidation="true">
+        <property name="additionalAudiencesLookupStrategy">
+            <bean class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.ExtraAudiencesLookupStrategy" 
+                c:relyingPartyContextLookupStrategy-ref="shibboleth.ChildLookup.RelyingParty"/>
+        </property>    
+    </bean>
+        
     <bean id="ClientIDFromOAuth2ClientContextFunction"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.ClientIDFromOAuth2ClientContextFunction"
         c:oauth2ClientContextLookupStrategy-ref="shibboleth.ChildLookup.OAuth2ClientContextFromOutbound" />
 
-
-
     <bean id="NonceClaimValidator" class="net.shibboleth.oidc.security.jwt.claims.impl.ExactMatchClaimsValidator"
         p:claimName="nonce"
         p:valueToMatchLookupStrategy="#{getObject('shibboleth.authn.oidc.rp.jwt.NonceLookupStrategy') ?: 
@@ -642,7 +626,6 @@
     <bean id="shibboleth.authn.oidc.rp.jwt.DefaultNonceLookupStrategy"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.security.impl.AuthenticationRequestNonceClaimLookupStrategy" />
 
-
     <bean id="OIDCMetadataContextChildLookup" class="org.opensaml.messaging.context.navigate.ChildContextLookup"
         c:type="#{ T(net.shibboleth.oidc.metadata.context.OIDCMetadataContext) }" />
 
@@ -661,32 +644,35 @@
     
     <bean id="shibboleth.authn.oidc.rp.jwt.DefaultIDTokenJOSEHeaderLookupStrategy" 
         class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.IDTokenJOSEHeaderLookupStrategy"/>
-
-    <util:list id="IDTokenClaimsValidators" value-type="net.shibboleth.oidc.jwt.claims.ClaimsValidator">
-        <ref bean="IDTokenRequiredClaimsValidator" />
-        <ref bean="IssuerClaimsValidator" /> <!-- TODO prevent: if it contains additional audiences not trusted by the Client. -->
-        <ref bean="AudienceClaimsValidator" />
-        <ref bean="AzpClaimRequiredValidator" />
-        <ref bean="AzpClaimsValidator" />
-        <ref bean="ExpiryClaimsValidator" />
-        <ref bean="IssuedAtClaimsValidator" />
-        <ref bean="NotBeforeClaimsValidator" />
-        <ref bean="NonceClaimValidator" />
-        <ref bean="AtHashValidator"/>
-        <!-- missing ACR? and auth_time -->
-    </util:list>
-
-
+    
+    <bean id="AuthenticationTimeClaimValidator" 
+                class="net.shibboleth.oidc.security.jwt.claims.impl.AuthenticationTimeClaimsValidator"
+                p:authnLifetime="%{idp.authn.oidc.rp.client.idtoken.jwt.verifier.authLifetime:PT60S}"
+                p:clockSkew="%{idp.authn.oidc.rp.client.idtoken.jwt.verifier.clockSkew:PT60S}"
+                p:activationCondition="#{getObject('shibboleth.authn.oidc.rp.jwt.AuthTimeActivationCondition') ?: 
+                                getObject('shibboleth.authn.oidc.rp.jwt.DefaultAuthTimeActivationCondition')}"/>
+
+    <bean id="shibboleth.authn.oidc.rp.jwt.DefaultAuthTimeActivationCondition" 
+            class="net.shibboleth.oidc.security.jwt.claims.impl.AuthTimeRequestedActivationCondition"
+            c:authenticationRequestLookupStrategy-ref="shibboleth.ChildLookup.MessageLookup.Outbound.OIDCAuthenticationRequest"/>
+
+    <bean id="ACRClaimValidator" class="net.shibboleth.oidc.security.jwt.claims.impl.ACRClaimsValidator"
+        p:requestedEssentialAcrsClaimLookupStrategy="#{getObject('shibboleth.authn.oidc.rp.jwt.RequestedEssentialAcrsClaimLookupStrategy') ?: 
+                                getObject('shibboleth.authn.oidc.rp.jwt.DefaultRequestedEssentialAcrsClaimLookupStrategy')}"/>
+    
+    <bean id="shibboleth.authn.oidc.rp.jwt.DefaultRequestedEssentialAcrsClaimLookupStrategy" 
+                class="net.shibboleth.oidc.security.jwt.claims.impl.RequestedEssentialACRClaimsLookupStrategy"
+                c:authenticationRequestLookupStrategy-ref="shibboleth.ChildLookup.MessageLookup.Outbound.OIDCAuthenticationRequest"/>
+    
+    <!-- UserInfo Endpoint Beans -->
+    
     <bean id="CheckUserInfoRequiredCondition"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.messaging.context.logic.UserInfoLookupCondition" />
 
     <bean id="TokenResponsePopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:fieldExtractors="#{getObject('shibboleth.authn.oidc.rp.TokenResponseAuditExtractors') ?: getObject('shibboleth.authn.oidc.rp.DefaultTokenResponseAuditExtractors')}" />
-
-
-    <!-- UserInfo endpoint beans -->
-
+    
     <bean id="UserInfoEndpointLookup" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.UserInfoEndpointLookup"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
@@ -696,7 +682,6 @@
         p:httpResponseDecoderStrategy="#{getObject('shibboleth.authn.oidc.rp.UserInfoResponseDecoder') ?: getObject('shibboleth.authn.oidc.rp.DefaultUserInfoResponseDecoder')}"
         p:httpRequestEncoderStrategy="#{getObject('shibboleth.authn.oidc.rp.UserInfoRequestEncoder') ?: getObject('shibboleth.authn.oidc.rp.DefaultUserInfoRequestEncoder')}" />
 
-
     <bean id="shibboleth.authn.oidc.rp.DefaultUserInfoResponseDecoder" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.decoding.impl.DefaultUserInfoResponseDecoder"
         p:objectMapper-ref="shibboleth.authn.oidc.rp.JSONObjectMapper" />
@@ -714,7 +699,6 @@
         p:configurationLookupStrategy-ref="UserInfoTokenDecryptionConfigurationLookup"
         p:decryptionParametersResolver-ref="JWTDecryptionParametersResolver" />
 
-
     <bean id="UserInfoTokenDecryptionConfigurationLookup" lazy-init="true"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.UserInfoDecryptionConfigurationLookupFunction"
         p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver" />
@@ -746,6 +730,7 @@
             <bean class="org.opensaml.messaging.handler.impl.BasicMessageHandlerChain">
                 <property name="handlers">
                     <list>
+                    
                         <bean scope="prototype" class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureValidationParametersHandler">
                             <property name="signatureValidationParametersResolver">
                                 <bean class="net.shibboleth.oidc.security.impl.BasicJWTSignatureValidationParametersResolver" />
@@ -758,7 +743,7 @@
                         
                         <bean
                             class="net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl.OIDCProviderMetadataLookupHandler"
-                            scope="prototype" p:copyContextStrategy-ref="OutboundOIDCMetadataContextLookup"
+                            scope="prototype" p:copyContextStrategy-ref="shibboleth.ChildLookup.OutboundOIDCMetadataContextLookup"
                             p:providerMetadataResolver-ref="shibboleth.authn.oidc.rp.ProviderMetadataResolver" />
                             
                             
@@ -775,10 +760,14 @@
                                 <ref bean="shibboleth.ChildLookup.OIDCProviderMetadataFromPeerEntityContext" />
                             </property>
                         </bean>
+                        
                     </list>
                 </property>
             </bean>
         </constructor-arg>
+        <property name="errorEvent">
+            <util:constant static-field="org.opensaml.profile.action.EventIds.INVALID_MESSAGE" />
+        </property>
     </bean>
 
     <bean id="shibboleth.authn.oidc.rp.DefaultUserInfoTokenLookupStrategy"
@@ -790,14 +779,20 @@
         p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup"
         p:cleanupHook="#{getObject('shibboleth.authn.oidc.rp.userinfo.jwt.claims.CleanUpHook')}"
         p:claimsValidator="#{getObject('shibboleth.authn.oidc.rp.userinfo.UserInfoTokenClaimsValidator') 
-           ?: getObject('DefaultUserInfoTokenClaimsValidator')}"
+           ?: getObject('shibboleth.authn.oidc.rp.userinfo.DefaultUserInfoTokenClaimsValidator')}"
         p:jwtLookupStrategy="#{getObject('shibboleth.authn.oidc.rp.userinfo.UserInfoTokenLookupStrategy') 
            ?: getObject('shibboleth.authn.oidc.rp.DefaultUserInfoTokenLookupStrategy')}" />
 
-    <bean id="DefaultUserInfoTokenClaimsValidator"
+    <bean id="shibboleth.authn.oidc.rp.userinfo.DefaultUserInfoTokenClaimsValidator"
         class="net.shibboleth.oidc.security.jwt.claims.impl.ChainingJWTClaimsValidator"
         p:claimValidators-ref="UserInfoClaimsValidators" />
 
+    <util:list id="UserInfoClaimsValidators" value-type="net.shibboleth.oidc.jwt.claims.ClaimsValidator">
+        <ref bean="UserInfoTokenRequiredClaimsValidator" />
+        <ref bean="SubMatchesIDTokenClaimValidator" />
+        <ref bean="IssuerClaimsValidator" />
+        <ref bean="AudienceClaimsValidator" />
+    </util:list>
 
     <bean id="UserInfoTokenRequiredClaimsValidator"
         class="net.shibboleth.oidc.security.jwt.claims.impl.RequiredClaimsValidator">
@@ -815,18 +810,10 @@
         </property>
     </bean>
 
-    <util:list id="UserInfoClaimsValidators" value-type="net.shibboleth.oidc.jwt.claims.ClaimsValidator">
-        <ref bean="UserInfoTokenRequiredClaimsValidator" />
-        <ref bean="SubMatchesIDTokenClaimValidator" />
-        <ref bean="IssuerClaimsValidator" />
-        <ref bean="AudienceClaimsValidator" />
-    </util:list>
-
     <bean id="PostJWTUserInfoResponsePopulateAuditContext" parent="shibboleth.AbstractPopulateAuditContext"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:fieldExtractors="#{getObject('shibboleth.authn.oidc.rp.PostJWTUserInfoResponseAuditExtractors') ?: getObject('shibboleth.authn.oidc.rp.DefaultPostJWTUserInfoResponseAuditExtractors')}" />
 
-
     <!-- This is a very simplified and hard coded version of the claims verification used for a JWT. Maybe look to replace -->
     <bean id="ValidateUserInfoPlainResponseClaims" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.ValidateUserInfoJSONObjectClaims"
@@ -837,15 +824,12 @@
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:fieldExtractors="#{getObject('shibboleth.authn.oidc.rp.PostPlainUserInfoResponseAuditExtractors') ?: getObject('shibboleth.authn.oidc.rp.DefaultPostPlainUserInfoResponseAuditExtractors')}" />
 
-
-
     <bean id="ProcessEndUserClaims" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.ProcessEndUserClaims"
         scope="prototype" p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup"
         p:claimMergingStrategy="#{getObject('shibboleth.authn.oidc.rp.ClaimMergingStrategy') ?: getObject('shibboleth.authn.oidc.rp.DefaultClaimMergingStrategy')}"
         p:claimSanitizationStrategy="#{getObject('shibboleth.authn.oidc.rp.ClaimSanitizationStrategy') ?: getObject('shibboleth.authn.oidc.rp.DefaultClaimSanitizationStrategy')}" />
 
-
     <bean id="shibboleth.authn.oidc.rp.DefaultClaimMergingStrategy"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.DefaultClaimMergingStrategy" />
 
@@ -859,7 +843,6 @@
     <bean id="CheckUserInfoPlainResponseTypeCondition"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.messaging.context.logic.UserInfoPlainResponseTypeCondition" />
 
-
     <!-- Final validation and proxy authentication result -->
 
     <bean id="ValidateOIDCAuthentication"
@@ -888,8 +871,10 @@
     <bean id="UnsupportedResponseTypeAction"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.UnsupportedResponseTypeAction" />
 
-    <!-- Allows the WriteAuditLog action to be run in a transition, and a 'success' event is produced such that the transition 
-        is executed. -->
+    <!-- 
+        Allows the WriteAuditLog action to be run in a transition, and a 'success' event is produced such that the transition 
+        is executed.
+    -->
     <bean id="WriteAuditLogInTransition"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.audit.impl.TransitionActionWriteAuditLog" scope="prototype"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
@@ -899,7 +884,6 @@
         p:httpServletRequest-ref="shibboleth.authn.oidc.rp.internal.HttpServletRequest" />
 
 
-
     <!-- Can override one or more of the beans above. Note, the property override is mostly to allow tests to change the 
         location of the user config file. -->
     <import

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


More information about the commits mailing list