[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