[java-idp-plugin-oidc-rp] branch main updated: Allow TLS server verification only for signed id_token
Phil Smart
philip.smart at jisc.ac.uk
Wed Nov 30 12:25: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=8ab8b42c8e94123ce14b593e8b479c9f7e2ce321
The following commit(s) were added to refs/heads/main by this push:
new 8ab8b42 Allow TLS server verification only for signed id_token
8ab8b42 is described below
commit 8ab8b42c8e94123ce14b593e8b479c9f7e2ce321
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Wed Nov 30 12:25:47 2022 +0000
Allow TLS server verification only for signed id_token
- TLS server validation MAY be used to validate the issuer in place of
checking the token signature
---
.../RequiresSignatureVerificationPredicate.java | 92 +++++++++++++++++++++
...tureValidationConfigurationLookupFunction.java} | 25 +++---
...atureValidationConfigurationLookupFunction.java | 93 ----------------------
...RequiresSignatureVerificationPredicateTest.java | 59 ++++++++++++++
.../idp/plugin/authn/oidc/rp/impl/DecryptJWT.java | 2 +-
.../META-INF/net.shibboleth.idp/postconfig.xml | 9 ++-
.../oidc-relying-party-authn-beans.xml | 80 +++++++++----------
.../oidc-relying-party-authn-flow.xml | 9 +--
.../authn/oidc/rp/conf/authn/oidc-rp.properties | 3 +
9 files changed, 220 insertions(+), 152 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
new file mode 100644
index 0000000..226b666
--- /dev/null
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/RequiresSignatureVerificationPredicate.java
@@ -0,0 +1,92 @@
+/*
+ * 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.idp.plugin.authn.oidc.rp.config.logic;
+
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.idp.plugin.authn.oidc.rp.context.AbstractAuthenticatableOIDCContext;
+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 —
+ * signature verification is required.
+ */
+public class RequiresSignatureVerificationPredicate implements Predicate<MessageContext> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(RequiresSignatureVerificationPredicate.class);
+
+ /**
+ * If true and the {@link AbstractAuthenticatableOIDCContext} is authenticated, the predicate
+ * returns false (no additional signature verification required).
+ */
+ private boolean tlsServerValidationOnly;
+
+ /** Strategy used to lookup the {@link AbstractAuthenticatableOIDCContext} to test. */
+ @Nonnull
+ private final Function<MessageContext, AbstractAuthenticatableOIDCContext> authenticatableOIDCContextLookupStrategy;
+
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param strategy the strategy used to locate the {@link AbstractAuthenticatableOIDCContext} to test
+ */
+ public RequiresSignatureVerificationPredicate(@Nonnull @ParameterName(name="authenticatableOIDCContextLookupStrategy")
+ final Function<MessageContext, AbstractAuthenticatableOIDCContext> strategy) {
+ super();
+ authenticatableOIDCContextLookupStrategy = Constraint.isNotNull(strategy,
+ "authenticatableOIDCContextLookupStrategy can not be null");
+ }
+
+ /**
+ * Set whether TLS server validation is sufficient (true), or if JWT signature verification should
+ * still occur (false).
+ *
+ * @param flag the flag
+ */
+ public void setTlsServerValidationOnly(final boolean flag) {
+ tlsServerValidationOnly = flag;
+ }
+
+ @Override
+ public boolean test(@Nonnull final MessageContext msgContext) {
+
+ final AbstractAuthenticatableOIDCContext authContext =
+ authenticatableOIDCContextLookupStrategy.apply(msgContext);
+
+ if (tlsServerValidationOnly && authContext.isAuthenticated()) {
+ // No further validation required.
+ log.debug("TLS server validation was successful and sufficient, no further signature processing performed");
+ return false;
+ }
+
+ return true;
+
+ }
+
+}
diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/IDTokenSignatureValidationConfigurationLookupFunction.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/JWTSignatureValidationConfigurationLookupFunction.java
similarity index 78%
rename from idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/IDTokenSignatureValidationConfigurationLookupFunction.java
rename to idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/JWTSignatureValidationConfigurationLookupFunction.java
index 7853405..79076f7 100644
--- a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/IDTokenSignatureValidationConfigurationLookupFunction.java
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/JWTSignatureValidationConfigurationLookupFunction.java
@@ -22,25 +22,25 @@ import java.util.List;
import javax.annotation.Nullable;
-import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.messaging.context.MessageContext;
import net.shibboleth.idp.profile.config.ProfileConfiguration;
import net.shibboleth.idp.profile.config.SecurityConfiguration;
import net.shibboleth.idp.profile.context.RelyingPartyContext;
-import net.shibboleth.idp.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.idp.profile.context.navigate.messaging.AbstractRelyingPartyLookupFunction;
import net.shibboleth.idp.relyingparty.RelyingPartyConfigurationResolver;
import net.shibboleth.oidc.profile.config.OIDCSecurityConfiguration;
import net.shibboleth.oidc.security.JWTSignatureValidationConfiguration;
/**
- * A function that returns a {@link JWTSignatureValidationConfiguration} list for id_token signature validation by way
+ * A function that returns a {@link JWTSignatureValidationConfiguration} list for JWS validation by way
* of various lookup strategies.
*
* <p>
* If a specific setting is unavailable, a null value is returned.
* </p>
*/
-public class IDTokenSignatureValidationConfigurationLookupFunction
+public class JWTSignatureValidationConfigurationLookupFunction
extends AbstractRelyingPartyLookupFunction<List<JWTSignatureValidationConfiguration>> {
/** A resolver for default security configurations. */
@@ -59,17 +59,21 @@ public class IDTokenSignatureValidationConfigurationLookupFunction
/** {@inheritDoc} */
@Override
@Nullable
- public List<JWTSignatureValidationConfiguration> apply(@Nullable final ProfileRequestContext input) {
+ public List<JWTSignatureValidationConfiguration> apply(@Nullable final MessageContext input) {
final List<JWTSignatureValidationConfiguration> configs = new ArrayList<>();
final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
if (rpc != null) {
final ProfileConfiguration pc = rpc.getProfileConfig();
- if (pc != null && pc.getSecurityConfiguration(input) instanceof OIDCSecurityConfiguration
- && ((OIDCSecurityConfiguration) pc.getSecurityConfiguration(input))
- .getJwtSignatureValidationConfiguration() != null) {
- configs.add(((OIDCSecurityConfiguration) pc.getSecurityConfiguration(input))
+ if (pc != null &&
+ pc.getSecurityConfiguration(getProfileRequestContextLookupStrategy().apply(input))
+ instanceof OIDCSecurityConfiguration
+ && ((OIDCSecurityConfiguration) pc.getSecurityConfiguration(
+ getProfileRequestContextLookupStrategy().apply(input)))
+ .getJwtSignatureValidationConfiguration() != null) {
+ configs.add(((OIDCSecurityConfiguration) pc.getSecurityConfiguration(
+ getProfileRequestContextLookupStrategy().apply(input)))
.getJwtSignatureValidationConfiguration());
}
}
@@ -77,7 +81,8 @@ public class IDTokenSignatureValidationConfigurationLookupFunction
// Check for a per-profile default (relying party independent) config.
if (input != null && rpResolver != null) {
final SecurityConfiguration defaultConfig =
- rpResolver.getDefaultSecurityConfiguration(input.getProfileId());
+ rpResolver.getDefaultSecurityConfiguration(
+ getProfileRequestContextLookupStrategy().apply(input).getProfileId());
if (defaultConfig instanceof OIDCSecurityConfiguration
&& ((OIDCSecurityConfiguration) defaultConfig)
.getJwtSignatureValidationConfiguration() != null) {
diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/UserInfoTokenSignatureValidationConfigurationLookupFunction.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/UserInfoTokenSignatureValidationConfigurationLookupFunction.java
deleted file mode 100644
index be202e4..0000000
--- a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/UserInfoTokenSignatureValidationConfigurationLookupFunction.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.idp.plugin.authn.oidc.rp.config.navigate;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.annotation.Nullable;
-
-import org.opensaml.profile.context.ProfileRequestContext;
-
-import net.shibboleth.idp.profile.config.ProfileConfiguration;
-import net.shibboleth.idp.profile.config.SecurityConfiguration;
-import net.shibboleth.idp.profile.context.RelyingPartyContext;
-import net.shibboleth.idp.profile.context.navigate.AbstractRelyingPartyLookupFunction;
-import net.shibboleth.idp.relyingparty.RelyingPartyConfigurationResolver;
-import net.shibboleth.oidc.profile.config.OIDCSecurityConfiguration;
-import net.shibboleth.oidc.security.JWTSignatureValidationConfiguration;
-
-/**
- * A function that returns a {@link JWTSignatureValidationConfiguration} list for UserInfo token signature validation
- * by way of various lookup strategies.
- *
- * <p>
- * If a specific setting is unavailable, a null value is returned.
- * </p>
- */
-public class UserInfoTokenSignatureValidationConfigurationLookupFunction
- extends AbstractRelyingPartyLookupFunction<List<JWTSignatureValidationConfiguration>> {
-
- /** A resolver for default security configurations. */
- @Nullable
- private RelyingPartyConfigurationResolver rpResolver;
-
- /**
- * Set the resolver for default security configurations.
- *
- * @param resolver the resolver to use
- */
- public void setRelyingPartyConfigurationResolver(@Nullable final RelyingPartyConfigurationResolver resolver) {
- rpResolver = resolver;
- }
-
- /** {@inheritDoc} */
- @Override
- @Nullable
- public List<JWTSignatureValidationConfiguration> apply(@Nullable final ProfileRequestContext input) {
-
- final List<JWTSignatureValidationConfiguration> configs = new ArrayList<>();
-
- final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
- if (rpc != null) {
- final ProfileConfiguration pc = rpc.getProfileConfig();
- if (pc != null && pc.getSecurityConfiguration(input) instanceof OIDCSecurityConfiguration
- && ((OIDCSecurityConfiguration) pc.getSecurityConfiguration(input))
- .getJwtSignatureValidationConfiguration() != null) {
- configs.add(((OIDCSecurityConfiguration) pc.getSecurityConfiguration(input))
- .getJwtSignatureValidationConfiguration());
- }
- }
-
- // Check for a per-profile default (relying party independent) config.
- if (input != null && rpResolver != null) {
- final SecurityConfiguration defaultConfig =
- rpResolver.getDefaultSecurityConfiguration(input.getProfileId());
- if (defaultConfig instanceof OIDCSecurityConfiguration
- && ((OIDCSecurityConfiguration) defaultConfig)
- .getJwtSignatureValidationConfiguration() != null) {
- configs.add(
- ((OIDCSecurityConfiguration) defaultConfig)
- .getJwtSignatureValidationConfiguration());
- }
- }
- // TODO: Support for Global Default configuration?
- return configs;
- }
-}
-
diff --git a/idp-oidc-rp-api/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/RequiresSignatureVerificationPredicateTest.java b/idp-oidc-rp-api/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/RequiresSignatureVerificationPredicateTest.java
new file mode 100644
index 0000000..7776f73
--- /dev/null
+++ b/idp-oidc-rp-api/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/RequiresSignatureVerificationPredicateTest.java
@@ -0,0 +1,59 @@
+
+package net.shibboleth.idp.plugin.authn.oidc.rp.config.logic;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.testng.annotations.Test;
+
+import net.shibboleth.idp.plugin.authn.oidc.rp.context.AbstractAuthenticatableOIDCContext;
+
+public class RequiresSignatureVerificationPredicateTest {
+
+ /** The predicate to test*/
+ private RequiresSignatureVerificationPredicate predicate;
+
+
+
+ @Test
+ public void testSignatureVerificationRequired_TLSOnlyDisabled() {
+ predicate = new RequiresSignatureVerificationPredicate(msg -> new MockAuthenticatableContext(true));
+ predicate.setTlsServerValidationOnly(false);
+
+ assertTrue(predicate.test(new MessageContext()));
+ }
+
+ @Test
+ public void testSignatureVerificationRequired_TLSOnlyDisabled_ContextNotAuthenticated() {
+ predicate = new RequiresSignatureVerificationPredicate(msg -> new MockAuthenticatableContext(false));
+ predicate.setTlsServerValidationOnly(false);
+
+ assertTrue(predicate.test(new MessageContext()));
+ }
+
+ @Test
+ public void testSignatureVerificationRequired_TLSOnlyEnabled_ContextNotAuthenticated() {
+ predicate = new RequiresSignatureVerificationPredicate(msg -> new MockAuthenticatableContext(false));
+ predicate.setTlsServerValidationOnly(true);
+
+ assertTrue(predicate.test(new MessageContext()));
+ }
+
+ @Test
+ public void testSignatureVerificationNotRequired_TLSOnlyEnabled() {
+ predicate = new RequiresSignatureVerificationPredicate(msg -> new MockAuthenticatableContext(true));
+ predicate.setTlsServerValidationOnly(true);
+
+ assertFalse(predicate.test(new MessageContext()));
+ }
+
+ /** Mock Authenticatable context.*/
+ private static class MockAuthenticatableContext extends AbstractAuthenticatableOIDCContext {
+
+ private MockAuthenticatableContext(final boolean authn) {
+ super.setAuthenticated(authn);
+ }
+ }
+
+}
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/DecryptJWT.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/DecryptJWT.java
index 982e706..226c998 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/DecryptJWT.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/DecryptJWT.java
@@ -144,7 +144,7 @@ public class DecryptJWT extends AbstractProfileAction {
encryptedJwt = jwtTokenLookupStrategy.apply(profileRequestContext);
if (encryptedJwt == null) {
- log.debug("{} JWT was not an Encrypted, nothing to decrypt",
+ log.debug("{} JWT was not encrypted, nothing to decrypt",
getLogPrefix());
return false;
}
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 0b6cc94..3e7dff0 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
@@ -41,7 +41,11 @@
<bean id="shibboleth.ChildLookup.OIDCPeerEntityContext"
class="org.opensaml.messaging.context.navigate.ChildContextLookup"
c:type="#{ T(net.shibboleth.idp.plugin.authn.oidc.rp.context.OIDCPeerEntityContext) }" />
-
+
+ <bean id="shibboleth.ChildLookup.AccessTokenResponseContext"
+ class="org.opensaml.messaging.context.navigate.ChildContextLookup"
+ c:type="#{ T(net.shibboleth.idp.plugin.authn.oidc.rp.context.AccessTokenResponseContext) }" />
+
<bean id="shibboleth.ChildLookup.OIDCProviderMetadataContextFromOutbound" parent="shibboleth.Functions.Compose">
<constructor-arg name="g">
<ref bean="shibboleth.ChildLookup.OIDCProviderMetadataContext" />
@@ -134,6 +138,9 @@
<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" />
<!-- 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 21a8916..9c21aae 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
@@ -462,34 +462,29 @@
<!-- ID TOKEN Signature Validation -->
- <bean id="PopulateIDTokenSignatureValidationParameters" parent="NestedWebFlowProfileActionAdaptor"
- scope="prototype">
- <constructor-arg>
- <bean class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureValidationParameters"
- c:strategy-ref="shibboleth.MessageContextLookup.Inbound"
- p:configurationLookupStrategy-ref="shibboleth.authn.oidc.rp.IDTokenSignatureValidationConfigurationLookup"
- p:signatureValidationParametersResolver-ref="shibboleth.authn.oidc.rp.IDTokenJwtSignatureValidationParametersResolver" />
- </constructor-arg>
- </bean>
-
- <bean id="shibboleth.authn.oidc.rp.IDTokenJwtSignatureValidationParametersResolver"
- class="net.shibboleth.oidc.security.impl.BasicJWTSignatureValidationParametersResolver" />
-
- <bean id="shibboleth.authn.oidc.rp.IDTokenSignatureValidationConfigurationLookup"
- class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.IDTokenSignatureValidationConfigurationLookupFunction"
- p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver" />
-
- <!-- TODO should we handle claims validation here as well? -->
- <bean id="HandleIDTokenValidation" parent="NestedWebFlowMessageHandlerAdaptor" scope="prototype"
+ <bean id="IDTokenSignatureValidation" parent="NestedWebFlowMessageHandlerAdaptor" scope="prototype"
c:executionDirection="INBOUND">
<constructor-arg>
- <bean class="org.opensaml.messaging.handler.impl.BasicMessageHandlerChain">
+ <bean class="org.opensaml.messaging.handler.impl.BasicMessageHandlerChain"
+ p:activationCondition-ref="IDTokenRequiresSignatureVerificationCondition">
<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" />
+ </property>
+ <property name="configurationLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.JWTSignatureValidationConfigurationLookupFunction"
+ p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver" />
+ </property>
+ </bean>
+
<bean
class="net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl.OIDCProviderMetadataLookupHandler"
scope="prototype" p:copyContextStrategy-ref="OutboundOIDCMetadataContextLookup"
p:providerMetadataResolver-ref="shibboleth.authn.oidc.rp.ProviderMetadataResolver" />
+
<bean class="net.shibboleth.oidc.security.impl.JWTMessageSignatureSecurityHandler"
scope="prototype">
<property name="jwtTokenLookupStrategy">
@@ -503,13 +498,17 @@
<ref bean="shibboleth.ChildLookup.OIDCProviderMetadataFromPeerEntityContext" />
</property>
</bean>
+
</list>
</property>
</bean>
</constructor-arg>
</bean>
-
-
+
+ <bean id="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">
@@ -723,34 +722,33 @@
</property>
</bean>
- <bean id="PopulateUserInfoTokenSignatureValidationParameters" parent="NestedWebFlowProfileActionAdaptor"
- scope="prototype">
- <constructor-arg>
- <bean class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureValidationParameters"
- c:strategy-ref="shibboleth.MessageContextLookup.Inbound"
- p:configurationLookupStrategy-ref="UserInfoTokenSignatureValidationConfigurationLookup"
- p:signatureValidationParametersResolver-ref="UserInfoTokenJwtSignatureValidationParametersResolver" />
- </constructor-arg>
- </bean>
-
- <bean id="UserInfoTokenJwtSignatureValidationParametersResolver"
- class="net.shibboleth.oidc.security.impl.BasicJWTSignatureValidationParametersResolver" />
-
- <bean id="UserInfoTokenSignatureValidationConfigurationLookup"
- class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.UserInfoTokenSignatureValidationConfigurationLookupFunction"
- p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver" />
-
- <bean id="HandleUserInfoTokenValidation" parent="NestedWebFlowMessageHandlerAdaptor" scope="prototype"
+ <!--
+ Note, this is identical in setup to the id_token signature validation flow as they both use the same config and trust engine.
+ the only difference is the location of the JWT to validate. Maybe they could be merged. Also, the populate steps may or may not
+ have already been performed in the id_token validation depending on the activation condition, so maybe those could be consolidated.
+ -->
+ <bean id="UserInfoTokenSignatureValidation" parent="NestedWebFlowMessageHandlerAdaptor" scope="prototype"
c:executionDirection="INBOUND">
<constructor-arg>
<bean class="org.opensaml.messaging.handler.impl.BasicMessageHandlerChain">
<property name="handlers">
<list>
- <!-- FIXME Do we need to copy this again, it was in the id_token sig validation -->
+ <bean scope="prototype" class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureValidationParametersHandler">
+ <property name="signatureValidationParametersResolver">
+ <bean class="net.shibboleth.oidc.security.impl.BasicJWTSignatureValidationParametersResolver" />
+ </property>
+ <property name="configurationLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.JWTSignatureValidationConfigurationLookupFunction"
+ p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver" />
+ </property>
+ </bean>
+
<bean
class="net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl.OIDCProviderMetadataLookupHandler"
scope="prototype" p:copyContextStrategy-ref="OutboundOIDCMetadataContextLookup"
p:providerMetadataResolver-ref="shibboleth.authn.oidc.rp.ProviderMetadataResolver" />
+
+
<bean class="net.shibboleth.oidc.security.impl.JWTMessageSignatureSecurityHandler"
scope="prototype">
<property name="jwtTokenLookupStrategy">
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
index b0d551a..d8ac1d0 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
@@ -118,9 +118,8 @@
<evaluate expression="ExtractIDTokenFromTokenResponse" />
<evaluate expression="PopulateIDTokenDecryptionParameters" />
<evaluate expression="DecryptJWT" />
- <evaluate expression="PopulateIDTokenSignatureValidationParameters" />
- <!-- TODO Not sure if HandleIDTokenValidation needs to be a message chain? -->
- <evaluate expression="HandleIDTokenValidation" />
+ <!--Validation of the JWT signature is optional if TLS server validation was performed -->
+ <evaluate expression="IDTokenSignatureValidation" />
<evaluate expression="ValidateIDTokenClaims" />
<evaluate expression="TokenResponsePopulateAuditContext" />
<evaluate expression="'proceed'" />
@@ -135,7 +134,6 @@
<action-state id="UserInfoRequest">
<evaluate expression="UserInfoEndpointLookup" />
- <!-- Something needs to check TLS server certificate? Not sure, performed by HTTP Client -->
<evaluate expression="'proceed'" />
<transition on="proceed" to="CheckUserInfoResponseType" />
</action-state>
@@ -150,8 +148,7 @@
<action-state id="ValidateUserInfoJWT">
<evaluate expression="PopulateUserInfoDecryptionParameters" />
<evaluate expression="DecryptUserInfoJWT" />
- <evaluate expression="PopulateUserInfoTokenSignatureValidationParameters" />
- <evaluate expression="HandleUserInfoTokenValidation" />
+ <evaluate expression="UserInfoTokenSignatureValidation" />
<evaluate expression="ValidateUserInfoTokenClaims" />
<evaluate expression="PostJWTUserInfoResponsePopulateAuditContext" />
<evaluate expression="'proceed'" />
diff --git a/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/oidc-rp.properties b/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/oidc-rp.properties
index 3b769db..188f1b7 100644
--- a/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/oidc-rp.properties
+++ b/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/oidc-rp.properties
@@ -16,6 +16,9 @@ idp.authn.oidc.rp.client.redirecturl.allowedOrigins = https://localhost:8443
#idp.authn.oidc.rp.client.requestobject.encrypted = false
#idp.authn.oidc.rp.client.requestobject.signed = true
+## If true and the token was retrieved using TLS with server validation, JWS signature checking will be skipped.
+#idp.authn.oidc.rp.client.idtoken.tlsServerValidationOnly = false
+
#idp.authn.oidc.rp.client.userinfo.enabled = true
#idp.authn.oidc.rp.client.userinfo.requireJWTResponse = false
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list