[java-oidc-common] 11/20: WIP: Add lookup strategies and contexts and predicates from the RP
Codeberg
noreply at shibboleth.net
Tue Feb 17 20:14:46 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch dev/JCOMOIDC-139
in repository java-oidc-common.
View the commit online:
https://codeberg.org/Shibboleth/java-oidc-common/commit/5998e093c61da2cca200fc1febee025936229863
commit 5998e093c61da2cca200fc1febee025936229863
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Nov 14 17:10:07 2025 +0000
WIP: Add lookup strategies and contexts and predicates from the RP
---
.../impl/AbstractTokenResponseLookupStrategy.java | 64 ++++++++++++
.../claims/impl/ExtraAudiencesLookupStrategy.java | 67 +++++++++++++
.../IDTokenFromResponseContextLookupStrategy.java | 61 ++++++++++++
.../impl/ManyValuesIntegerComparisonPredicate.java | 27 +++++
.../jwt/claims/impl/MaxAgeLookupFunction.java | 109 +++++++++++++++++++++
.../AbstractAuthenticatableOIDCContext.java | 49 +++++++++
.../context/AccessTokenResponseContext.java | 67 +++++++++++++
.../oidc/profile/context/EndUserClaimsContext.java | 85 ++++++++++++++++
.../oidc/profile/context/OAuth2ClientContext.java | 91 +++++++++++++++++
.../oidc/profile/context/OIDCAuthnContext.java | 94 ++++++++++++++++++
.../context/OutboundMessageHandlerContext.java | 69 +++++++++++++
.../profile/context/UserInfoResponseContext.java | 48 +++++++++
.../AbstractTokenResponseLookupStrategy.java | 64 ++++++++++++
.../navigate/AccessTokenLookupStrategy.java | 61 ++++++++++++
.../ClientIDFromOAuth2ClientContextFunction.java | 67 +++++++++++++
.../navigate/EncryptedIDTokenLookupStrategy.java | 83 ++++++++++++++++
.../IDTokenInAccessTokenUpdateStrategy.java | 88 +++++++++++++++++
.../navigate/IDTokenJOSEHeaderLookupStrategy.java | 67 +++++++++++++
...viderMetadataFromOuboundPeerLookupStrategy.java | 50 ++++++++++
.../profile/core/OAuthAuthorizationRequest.java | 13 ++-
20 files changed, 1323 insertions(+), 1 deletion(-)
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/AbstractTokenResponseLookupStrategy.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/AbstractTokenResponseLookupStrategy.java
new file mode 100644
index 00000000..4239fab3
--- /dev/null
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/AbstractTokenResponseLookupStrategy.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.security.jwt.claims.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+
+import net.shibboleth.oidc.profile.context.AccessTokenResponseContext;
+import net.shibboleth.shared.logic.Constraint;
+
+/** Base class for looking up the token response context.*/
+public abstract class AbstractTokenResponseLookupStrategy {
+
+ /** Strategy used to locate the {@link AccessTokenResponseContext} to extract the id_token from.*/
+ @Nonnull
+ private final Function<ProfileRequestContext, AccessTokenResponseContext> tokenResponseContextLookupStrategy;
+
+ /** Constructor.*/
+ protected AbstractTokenResponseLookupStrategy() {
+ tokenResponseContextLookupStrategy =
+ new ChildContextLookup<>(AccessTokenResponseContext.class, true).compose(
+ new InboundMessageContextLookup());
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param strategy the AccessTokenResponseContext lookup strategy to use.
+ */
+ protected AbstractTokenResponseLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, AccessTokenResponseContext> strategy) {
+ tokenResponseContextLookupStrategy =
+ Constraint.isNotNull(strategy, "AccessTokenResponseContext lookup strategy can not be null");
+ }
+
+ /**
+ * Get the token response context lookup strategy.
+ *
+ * @return the lookup strategy
+ */
+ @Nonnull
+ protected Function<ProfileRequestContext, AccessTokenResponseContext> getTokenResponseContextLookupStrategy() {
+ return tokenResponseContextLookupStrategy;
+ }
+
+}
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/ExtraAudiencesLookupStrategy.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/ExtraAudiencesLookupStrategy.java
new file mode 100644
index 00000000..3323a732
--- /dev/null
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/ExtraAudiencesLookupStrategy.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.security.jwt.claims.impl;
+
+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.oidc.profile.config.OIDCIDTokenProducingProfileConfiguration;
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * Locate additional accepted audiences from the 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 OIDCIDTokenProducingProfileConfiguration config) {
+ return config.getAdditionalAudiencesForIdToken(prc);
+ }
+ }
+ return Collections.emptySet();
+ }
+
+}
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/IDTokenFromResponseContextLookupStrategy.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/IDTokenFromResponseContextLookupStrategy.java
new file mode 100644
index 00000000..ced1fefd
--- /dev/null
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/IDTokenFromResponseContextLookupStrategy.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.security.jwt.claims.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.jwt.JWT;
+
+import net.shibboleth.oidc.profile.context.AccessTokenResponseContext;
+import net.shibboleth.shared.annotation.ParameterName;
+
+/** Function that extracts the id_token from the {@link AccessTokenResponseContext}.*/
+ at ThreadSafe
+public class IDTokenFromResponseContextLookupStrategy extends AbstractTokenResponseLookupStrategy
+ implements Function<ProfileRequestContext, JWT> {
+
+ /** Constructor.*/
+ public IDTokenFromResponseContextLookupStrategy() {
+ super();
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param strategy the AccessTokenResponseContext lookup strategy to use.
+ */
+ public IDTokenFromResponseContextLookupStrategy(@Nonnull @ParameterName(name="accessTokenContextLookupStrategy")
+ final Function<ProfileRequestContext, AccessTokenResponseContext> strategy) {
+ super(strategy);
+ }
+
+ @Override
+ @Nullable public JWT apply(@Nullable final ProfileRequestContext prc) {
+ final AccessTokenResponseContext tokenContext = getTokenResponseContextLookupStrategy().apply(prc);
+ final var tokenResponse = tokenContext != null ? tokenContext.getTokenResponse() : null;
+ if (tokenResponse == null || tokenResponse.getTokens() == null) {
+ return null;
+ }
+ return tokenResponse.getOIDCTokens().getIDToken();
+ }
+
+}
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/ManyValuesIntegerComparisonPredicate.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/ManyValuesIntegerComparisonPredicate.java
new file mode 100644
index 00000000..0aba65a6
--- /dev/null
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/ManyValuesIntegerComparisonPredicate.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.security.jwt.claims.impl;
+
+import java.util.function.IntPredicate;
+
+/** Predicate that returns true if the test integer is greater than 1.*/
+public class ManyValuesIntegerComparisonPredicate implements IntPredicate {
+
+ @Override
+ public boolean test(final int value) {
+ return value > 1;
+ }
+
+}
diff --git a/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/MaxAgeLookupFunction.java b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/MaxAgeLookupFunction.java
new file mode 100644
index 00000000..59363028
--- /dev/null
+++ b/oidc-common-crypto-impl/src/main/java/net/shibboleth/oidc/security/jwt/claims/impl/MaxAgeLookupFunction.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.security.jwt.claims.impl;
+
+import java.time.Duration;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.oidc.profile.config.OIDCAuthenticationProfileConfiguration;
+import net.shibboleth.oidc.profile.core.OIDCAuthenticationRequest;
+import net.shibboleth.profile.config.ProfileConfiguration;
+import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * Locate the maximum authentication age from the authentication request (first) or profile configuration (second).
+ * Returning a default value if neither are found.
+ */
+public class MaxAgeLookupFunction extends AbstractRelyingPartyLookupFunction<Duration> {
+
+ /** Default max authentication age if none can be found on the profile context.*/
+ @Nonnull private final Duration maxAgeDefault;
+
+ /**
+ * Strategy used to locate the {@link OIDCAuthenticationRequest}.
+ * Defaults to the outbound message context of the PRC.
+ */
+ @Nonnull private Function<ProfileRequestContext, OIDCAuthenticationRequest> authenticationRequestLookupStrategy;
+
+ /**
+ * Constructor.
+ *
+ * @param defaultAge the default value to use for maximum authentication age
+ */
+ public MaxAgeLookupFunction(
+ @ParameterName(name = "maxAgeDefault") @Nonnull final Duration defaultAge) {
+ maxAgeDefault = Constraint.isNotNull(defaultAge, "Max Age default can not be null");
+
+ authenticationRequestLookupStrategy = prc -> {
+ final MessageContext msgCtx = prc.getOutboundMessageContext();
+ if (msgCtx != null && msgCtx.getMessage() != null &&
+ msgCtx.getMessage() instanceof final OIDCAuthenticationRequest request) {
+ return request;
+ }
+ return null;
+ };
+ }
+
+ /**
+ * Set the authentication request lookup strategy to use.
+ *
+ * @param strategy the strategy
+ */
+ public void setAuthenticationRequestLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, OIDCAuthenticationRequest> strategy) {
+ authenticationRequestLookupStrategy = Constraint.isNotNull(strategy,
+ "AuthenticationRequestLookupStrategy can not be null");
+ }
+
+ @Override
+ @Nonnull
+ public Duration apply(@Nullable final ProfileRequestContext input) {
+
+ // Max_age from authentication request is authoritative over that from the profile config. Although if it
+ // exists in the profile config it should have already been set on the authentication request.
+
+ final OIDCAuthenticationRequest authnRequest = authenticationRequestLookupStrategy.apply(input);
+ final Duration authnRequestMaxAge = authnRequest != null ? authnRequest.getMaxAge() : null;
+ if (authnRequestMaxAge != null) {
+ return authnRequestMaxAge;
+ }
+
+ // Check one was not specified in the relying party context
+
+ final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+ if (rpc != null) {
+ final ProfileConfiguration pc = rpc.getProfileConfig();
+ if (pc instanceof final OIDCAuthenticationProfileConfiguration config){
+ final Duration maxAge = config.getMaxAuthenticationAge(input);
+ if (maxAge == null) {
+ return maxAgeDefault;
+ } else {
+ return maxAge;
+ }
+ }
+ }
+ return maxAgeDefault;
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/AbstractAuthenticatableOIDCContext.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/AbstractAuthenticatableOIDCContext.java
new file mode 100644
index 00000000..9a41609b
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/AbstractAuthenticatableOIDCContext.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context;
+
+import org.opensaml.messaging.context.BaseContext;
+
+/**
+ * An abstract base class for subcontexts that carry information which may be authenticated. For example,
+ * tokens received over TLS where server TLS credential validation was performed and successful.
+ */
+public class AbstractAuthenticatableOIDCContext extends BaseContext {
+
+ /** Flag indicating whether the information contained in this context has been authenticated. */
+ private boolean authenticated;
+
+ /**
+ * Gets the flag indicating whether the information contained in this context has been authenticated.
+ *
+ * @return Returns the authenticated flag.
+ */
+ public boolean isAuthenticated() {
+ return authenticated;
+ }
+
+ /**
+ * Sets the flag indicating whether the information contained in this context has been authenticated.
+ *
+ * @param flag The flag to set.
+ *
+ * @return this
+ */
+ public AbstractAuthenticatableOIDCContext setAuthenticated(final boolean flag) {
+ authenticated = flag;
+ return this;
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/AccessTokenResponseContext.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/AccessTokenResponseContext.java
new file mode 100644
index 00000000..3ac0dbca
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/AccessTokenResponseContext.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context;
+
+import java.time.Instant;
+
+import javax.annotation.Nullable;
+
+import com.nimbusds.openid.connect.sdk.OIDCTokenResponse;
+
+/**
+ * A context to hold an OIDC token request response. If authenticated, the Token was received over a TLS protected
+ * channel where TLS credential validation was performed and successful.
+ */
+public class AccessTokenResponseContext extends AbstractAuthenticatableOIDCContext {
+
+ /** The OAuth 2.0 and OIDC token response.*/
+ @Nullable private OIDCTokenResponse tokenResponse;
+
+ /** The time the token response was set onto this context.*/
+ @Nullable private Instant tokenResponseCreatedAt;
+
+
+ /**
+ * Set the OAuth 2.0 and OIDC Token Response.
+ *
+ * @param token the token response
+ *
+ * @return this
+ */
+ public AccessTokenResponseContext setTokenResponse(@Nullable final OIDCTokenResponse token) {
+ tokenResponse = token;
+ tokenResponseCreatedAt = Instant.now();
+ return this;
+ }
+
+ /**
+ * Get the OAuth 2.0 and OIDC Token Response.
+ *
+ * @return the token response
+ */
+ @Nullable public OIDCTokenResponse getTokenResponse() {
+ return tokenResponse;
+ }
+
+ /**
+ * Get the time the token response was set onto this context.
+ *
+ * @return the time the token response was set onto this context
+ */
+ @Nullable public Instant getTokenResponseCreatedAt() {
+ return tokenResponseCreatedAt;
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/EndUserClaimsContext.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/EndUserClaimsContext.java
new file mode 100644
index 00000000..8cfc49bf
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/EndUserClaimsContext.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.openid.connect.sdk.claims.ClaimsSet;
+
+import net.shibboleth.shared.logic.Constraint;
+
+/** A context to hold the final set of claims associated with an authenticated end-user.*/
+public class EndUserClaimsContext extends BaseContext {
+
+ /**
+ * The claims associated with the authenticated end-user.
+ * Often an aggregate of id_token and UserInfo claims
+ */
+ @Nullable private ClaimsSet endUserClaims;
+
+ /** The set of unprocessed id_token claims as returned from an id_token source.*/
+ @Nullable private JWTClaimsSet unprocessedIdTokenClaims;
+
+ /**
+ * Get the claims about the authenticated end-user.
+ *
+ * @return the claims.
+ */
+ @Nullable public ClaimsSet getEndUserClaims() {
+ return endUserClaims;
+ }
+
+ /**
+ * Set the claims about the authenticated end-user.
+ *
+ * @param claims the claims.
+ * @return this
+ */
+ public EndUserClaimsContext setEndUserClaims(@Nonnull final ClaimsSet claims) {
+ endUserClaims = Constraint.isNotNull(claims, "Claims can not be null");
+ return this;
+ }
+
+ /**
+ * Set the id_token claims about the authenticated end-user as returned from the id_token
+ * endpoint e.g. from a successful Token Response.
+ *
+ * <p>In contrast, the endUserClaims may contain both an aggregation of claims obtained from other
+ * sources e.g. the UserInfo endpoint, and a subset of the id_token claims e.g. only 'identity' claims
+ * and not 'validation' claims.</p>
+ *
+ * @param claims the id_token claims
+ *
+ * @return this
+ */
+ public EndUserClaimsContext setUnprocessedIdTokenClaims(@Nonnull final JWTClaimsSet claims) {
+ unprocessedIdTokenClaims = Constraint.isNotNull(claims,"ID Token claims can not be null");
+ return this;
+ }
+
+ /**
+ * Get the unproccessed id_token claims.
+ *
+ * @return the unprocessed id_token claims.
+ */
+ @Nullable public JWTClaimsSet getUnprocessedIdTokenClaims() {
+ return unprocessedIdTokenClaims;
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/OAuth2ClientContext.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/OAuth2ClientContext.java
new file mode 100644
index 00000000..21490d67
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/OAuth2ClientContext.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context;
+
+import java.net.URI;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+
+import net.shibboleth.oidc.profile.messaging.context.OIDCPeerEntityContext;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * A context to store information pertaining to the OAuth2 client (Relying Party) to use in communication
+ * with a OpenID Provider.
+ *
+ * <p>Typically a subcontext under {@link OIDCPeerEntityContext}, as it relates to the client
+ * associated pairwise with the upstream OP peer.</p>
+ *
+ * @parent {@link OIDCPeerEntityContext}
+ * @added During an OAuth 2.0 authentication request attempt
+ */
+public class OAuth2ClientContext extends BaseContext {
+
+ /** The client_id.*/
+ @Nullable private String clientId;
+
+
+ /** An redirect URI that should take preference over any automatically computed.*/
+ @Nullable private URI redirectUriOverride;
+
+
+ /**
+ * Set the redirect_uri to use in place of any other.
+ *
+ * @param override the redirect_uri
+ *
+ * @return this
+ */
+ public OAuth2ClientContext setRedirectUriOverride(@Nullable final URI override) {
+ redirectUriOverride = override;
+ return this;
+ }
+
+ /**
+ * Get the redirect_uri which should be used in place of any other.
+ *
+ * @return the redirect_uri
+ */
+ public URI getRedirectUriOverride() {
+ return redirectUriOverride;
+ }
+
+ /**
+ * Set the client_id.
+ *
+ * @param id the client_id
+ *
+ * @return this
+ */
+ public OAuth2ClientContext setClientId(@Nonnull @NotEmpty final String id) {
+ clientId = Constraint.isNotEmpty(id, "ClientID can not be null or empty");
+ return this;
+ }
+
+ /**
+ * Get the client_id.
+ *
+ * @return the client_id
+ */
+ public String getClientId() {
+ return clientId;
+ }
+
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/OIDCAuthnContext.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/OIDCAuthnContext.java
new file mode 100644
index 00000000..e70a71a6
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/OIDCAuthnContext.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+import org.opensaml.messaging.decoder.MessageDecoder;
+import org.opensaml.messaging.handler.MessageHandler;
+import org.opensaml.profile.action.ProfileAction;
+
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * Manages state during proxied OIDC authentication via a Spring Controller.
+ */
+public class OIDCAuthnContext extends BaseContext {
+
+ /** Outbound message handler to run prior to encoding. */
+ @Nullable private MessageHandler outboundMessageHandler;
+
+ /** Profile action to execute to produce outbound message response. */
+ @Nonnull private final ProfileAction encodeMessageAction;
+
+ /** The function to use to obtain a decoder. */
+ @Nonnull private final Function<String,MessageDecoder> decoderFactory;
+
+ /**
+ * Constructor.
+ *
+ * @param action message-encoding profile action
+ * @param factory the message descoder factory
+ */
+ public OIDCAuthnContext(@Nonnull final ProfileAction action,
+ @Nonnull final Function<String,MessageDecoder> factory) {
+ encodeMessageAction = Constraint.isNotNull(action, "Profile action cannot be null");
+ decoderFactory = Constraint.isNotNull(factory, "MessageDecoder factory cannot be null");
+ }
+
+ /**
+ * Get the message-encoding profile action.
+ *
+ * @return profile action
+ */
+ @Nonnull public ProfileAction getEncodeMessageAction() {
+ return encodeMessageAction;
+ }
+
+ /**
+ * Get the outbound {@link MessageHandler} to run prior to encoding.
+ *
+ * @return the outbound {@link MessageHandler}
+ */
+ @Nullable public MessageHandler getOutboundMessageHandler() {
+ return outboundMessageHandler;
+ }
+
+ /**
+ * Set the outbound {@link MessageHandler} to run prior to encoding.
+ *
+ * @param handler outbound {@link MessageHandler} to set
+ *
+ * @return this context
+ */
+ @Nonnull public OIDCAuthnContext setOutboundMessageHandler(@Nullable final MessageHandler handler) {
+ outboundMessageHandler = handler;
+ return this;
+ }
+
+ /**
+ * Get the factory function to obtain message decoders.
+ *
+ * @return factory function
+ */
+ @Nonnull public Function<String,MessageDecoder> getMessageDecoderFactory() {
+ return decoderFactory;
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/OutboundMessageHandlerContext.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/OutboundMessageHandlerContext.java
new file mode 100644
index 00000000..0c42af1d
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/OutboundMessageHandlerContext.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * A context to stash controller parameters for use by message handlers.
+ * For example, the OIDC RP preEncodeMessageHandlers.
+ */
+public class OutboundMessageHandlerContext extends BaseContext {
+
+ /** The spring webflow key.*/
+ @Nullable private String webflowKey;
+
+ /**
+ * Convenience constructor.
+ *
+ * @param key the swf key
+ */
+ public OutboundMessageHandlerContext(@Nonnull final String key) {
+ super();
+ webflowKey = Constraint.isNotNull(key, "Spring Webflow Key can not be null");
+ }
+
+ /** Constructor to allow no-arg construction.*/
+ public OutboundMessageHandlerContext() {
+ // Do nothing
+ }
+
+ /**
+ * Set the Spring Webflow execution key.
+ *
+ * @param key the swf execution key
+ *
+ * @return this
+ */
+ public OutboundMessageHandlerContext setWebflowKey(@Nonnull final String key) {
+ webflowKey = Constraint.isNotNull(key, "Spring Webflow Key can not be null");
+ return this;
+ }
+
+ /**
+ * Get the Spring Webflow execution key.
+ *
+ * @return Returns the webflowKey.
+ */
+ @Nullable public String getWebflowKey() {
+ return webflowKey;
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/UserInfoResponseContext.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/UserInfoResponseContext.java
new file mode 100644
index 00000000..797c7f91
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/UserInfoResponseContext.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context;
+
+import javax.annotation.Nullable;
+
+import com.nimbusds.openid.connect.sdk.UserInfoSuccessResponse;
+
+/** A context to hold the response from the UserInfo endpoint.*/
+public class UserInfoResponseContext extends AbstractAuthenticatableOIDCContext {
+
+ /** The UserInfo response.*/
+ @Nullable private UserInfoSuccessResponse userInfo;
+
+ /**
+ * Get the user info response.
+ *
+ * @return the user info.
+ */
+ @Nullable public UserInfoSuccessResponse getUserInfo() {
+ return userInfo;
+ }
+
+ /**
+ * Set the user info response.
+ *
+ * @param info the user info response.
+ *
+ * @return this
+ */
+ public UserInfoResponseContext setUserInfo(@Nullable final UserInfoSuccessResponse info) {
+ userInfo = info;
+ return this;
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/AbstractTokenResponseLookupStrategy.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/AbstractTokenResponseLookupStrategy.java
new file mode 100644
index 00000000..0a28dde9
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/AbstractTokenResponseLookupStrategy.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context.navigate;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+
+import net.shibboleth.oidc.profile.context.AccessTokenResponseContext;
+import net.shibboleth.shared.logic.Constraint;
+
+/** Base class for looking up the token response context.*/
+public abstract class AbstractTokenResponseLookupStrategy {
+
+ /** Strategy used to locate the {@link AccessTokenResponseContext} to extract the id_token from.*/
+ @Nonnull
+ private final Function<ProfileRequestContext, AccessTokenResponseContext> tokenResponseContextLookupStrategy;
+
+ /** Constructor.*/
+ protected AbstractTokenResponseLookupStrategy() {
+ tokenResponseContextLookupStrategy =
+ new ChildContextLookup<>(AccessTokenResponseContext.class, true).compose(
+ new InboundMessageContextLookup());
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param strategy the AccessTokenResponseContext lookup strategy to use.
+ */
+ protected AbstractTokenResponseLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, AccessTokenResponseContext> strategy) {
+ tokenResponseContextLookupStrategy =
+ Constraint.isNotNull(strategy, "AccessTokenResponseContext lookup strategy can not be null");
+ }
+
+ /**
+ * Get the token response context lookup strategy.
+ *
+ * @return the lookup strategy
+ */
+ @Nonnull
+ protected Function<ProfileRequestContext, AccessTokenResponseContext> getTokenResponseContextLookupStrategy() {
+ return tokenResponseContextLookupStrategy;
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/AccessTokenLookupStrategy.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/AccessTokenLookupStrategy.java
new file mode 100644
index 00000000..4411aec4
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/AccessTokenLookupStrategy.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context.navigate;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.oauth2.sdk.token.AccessToken;
+
+import net.shibboleth.oidc.profile.context.AccessTokenResponseContext;
+import net.shibboleth.shared.annotation.ParameterName;
+
+/** Function that extracts the access_token from the {@link AccessTokenResponseContext}.*/
+ at ThreadSafe
+public class AccessTokenLookupStrategy extends AbstractTokenResponseLookupStrategy
+ implements Function<ProfileRequestContext, AccessToken> {
+
+ /** Constructor.*/
+ public AccessTokenLookupStrategy() {
+ super();
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param strategy the AccessTokenResponseContext lookup strategy to use.
+ */
+ public AccessTokenLookupStrategy(@Nonnull @ParameterName(name="accessTokenContextLookupStrategy")
+ final Function<ProfileRequestContext, AccessTokenResponseContext> strategy) {
+ super(strategy);
+ }
+
+ @Override
+ @Nullable public AccessToken apply(@Nullable final ProfileRequestContext prc) {
+ final AccessTokenResponseContext tokenContext = getTokenResponseContextLookupStrategy().apply(prc);
+ final var tokenResponse = tokenContext != null ? tokenContext.getTokenResponse() : null;
+ if (tokenResponse == null || tokenResponse.getTokens() == null) {
+ return null;
+ }
+ return tokenResponse.getTokens().getAccessToken();
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/ClientIDFromOAuth2ClientContextFunction.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/ClientIDFromOAuth2ClientContextFunction.java
new file mode 100644
index 00000000..7f16168d
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/ClientIDFromOAuth2ClientContextFunction.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context.navigate;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+
+import net.shibboleth.oidc.profile.context.OAuth2ClientContext;
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * A function that pulls the client_id out of the {@link OAuth2ClientContext}.
+ */
+ at ThreadSafe
+public class ClientIDFromOAuth2ClientContextFunction
+ implements BiFunction<ProfileRequestContext, JWTClaimsSet, String> {
+
+ /** Lookup strategy that to return a {@link OAuth2ClientContext}. */
+ @Nonnull
+ private final Function<ProfileRequestContext, OAuth2ClientContext> oauth2ClientContextLookupStrategy;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param strgy the strategy used to locate the {@link OAuth2ClientContext}
+ */
+ public ClientIDFromOAuth2ClientContextFunction(
+ @Nonnull @ParameterName(name="oauth2ClientContextLookupStrategy")
+ final Function<ProfileRequestContext, OAuth2ClientContext> strgy) {
+ oauth2ClientContextLookupStrategy = Constraint.isNotNull(strgy,
+ "OAuth2 client context lookup strategy cannot be null");
+ }
+
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public String apply(@Nullable final ProfileRequestContext prc, @Nullable final JWTClaimsSet claimsSet) {
+ final OAuth2ClientContext clientContext = oauth2ClientContextLookupStrategy.apply(prc);
+ if (clientContext == null) {
+ return null;
+ }
+ return clientContext.getClientId();
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/EncryptedIDTokenLookupStrategy.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/EncryptedIDTokenLookupStrategy.java
new file mode 100644
index 00000000..7cd83648
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/EncryptedIDTokenLookupStrategy.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context.navigate;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.EncryptedJWT;
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.openid.connect.sdk.OIDCTokenResponse;
+
+import net.shibboleth.oidc.profile.context.AccessTokenResponseContext;
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Function that extracts the id_token from the {@link AccessTokenResponseContext} iff it is an {@link EncryptedJWT}
+ * type. If not {@code null} is returned.
+ */
+ at ThreadSafe
+public class EncryptedIDTokenLookupStrategy extends AbstractTokenResponseLookupStrategy
+ implements Function<ProfileRequestContext, JWT>{
+
+ /** Logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(EncryptedIDTokenLookupStrategy.class);
+
+ /** Constructor.*/
+ public EncryptedIDTokenLookupStrategy() {
+ super();
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param strategy the AccessTokenResponseContext lookup strategy to use.
+ */
+ public EncryptedIDTokenLookupStrategy(@ParameterName(name="accessTokenContextLookupStrategy")
+ @Nonnull final Function<ProfileRequestContext, AccessTokenResponseContext> strategy) {
+ super(strategy);
+ }
+
+ @Override
+ @Nullable public JWT apply(@Nullable final ProfileRequestContext prc) {
+ final AccessTokenResponseContext tokenContext = getTokenResponseContextLookupStrategy().apply(prc);
+ final OIDCTokenResponse tokenResponse = tokenContext != null ? tokenContext.getTokenResponse() : null;
+ if (tokenResponse == null) {
+ return null;
+ }
+ final JWT token = tokenResponse.getOIDCTokens().getIDToken();
+ if (token instanceof EncryptedJWT) {
+ log.trace("EncryptedIDToken Lookup: ID Token is encrypted using algorithm '{}'",
+ token.getHeader().getAlgorithm());
+ return token;
+ } else if (token instanceof SignedJWT){
+ log.trace("EncryptedIDToken Lookup: ID Token is signed and not encrypted, nothing to return");
+ return null;
+ } else {
+ log.trace("EncryptedIDToken Lookup: ID Token is neither signed nor encrypted, nothing to return");
+ return null;
+ }
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/IDTokenInAccessTokenUpdateStrategy.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/IDTokenInAccessTokenUpdateStrategy.java
new file mode 100644
index 00000000..d3b812b6
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/IDTokenInAccessTokenUpdateStrategy.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context.navigate;
+
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
+import org.slf4j.Logger;
+
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.openid.connect.sdk.OIDCTokenResponse;
+
+import net.minidev.json.JSONObject;
+import net.shibboleth.oidc.profile.context.AccessTokenResponseContext;
+import net.shibboleth.shared.annotation.ParameterName;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/** Consumer to update the id_token in the {@link AccessTokenResponseContext}.*/
+public class IDTokenInAccessTokenUpdateStrategy implements BiConsumer<ProfileRequestContext, JWT> {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(IDTokenInAccessTokenUpdateStrategy.class);
+
+ /** Strategy used to look up the {@link AccessTokenResponseContext} to set id_token on. */
+ @Nonnull private final Function<ProfileRequestContext, AccessTokenResponseContext>
+ tokenResponseContextLookupStrategy;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param strategy the strategy used look up the {@link AccessTokenResponseContext}.
+ */
+ public IDTokenInAccessTokenUpdateStrategy(@ParameterName(name="accessTokenContextLookupStrategy") final
+ Function<ProfileRequestContext, AccessTokenResponseContext> strategy) {
+
+ tokenResponseContextLookupStrategy =
+ Constraint.isNotNull(strategy, "accessTokenContextLookupStrategy can not be null");
+ }
+
+ /** Constructor.*/
+ public IDTokenInAccessTokenUpdateStrategy() {
+ tokenResponseContextLookupStrategy =
+ new ChildContextLookup<>(AccessTokenResponseContext.class, true).compose(
+ new InboundMessageContextLookup());
+ }
+
+ @Override
+ public void accept(final ProfileRequestContext profileRequestContext, final JWT idToken) {
+
+ final AccessTokenResponseContext context =
+ tokenResponseContextLookupStrategy.apply(profileRequestContext);
+ final OIDCTokenResponse tokenReponse = context != null ? context.getTokenResponse() : null;
+ if (context != null && tokenReponse != null) {
+ try {
+ // Create a new token response with the update id_token from the existing response
+ final JSONObject jsonToken = tokenReponse.toJSONObject();
+ jsonToken.put("id_token", idToken.serialize());
+ context.setTokenResponse(OIDCTokenResponse.parse(jsonToken));
+ } catch (final ParseException e) {
+ log.warn("Unable to set id_token back onto access token response", e);
+ }
+ } else {
+ log.warn("Unable to set id_token back onto access token response context");
+ }
+
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/IDTokenJOSEHeaderLookupStrategy.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/IDTokenJOSEHeaderLookupStrategy.java
new file mode 100644
index 00000000..2d0a15f5
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/IDTokenJOSEHeaderLookupStrategy.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context.navigate;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.jose.Header;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.openid.connect.sdk.OIDCTokenResponse;
+
+import net.shibboleth.oidc.profile.context.AccessTokenResponseContext;
+import net.shibboleth.shared.annotation.ParameterName;
+
+/** Function that extracts the JWS JOSE header from the id_token inside the {@link AccessTokenResponseContext}.*/
+ at ThreadSafe
+public class IDTokenJOSEHeaderLookupStrategy extends AbstractTokenResponseLookupStrategy
+ implements Function<ProfileRequestContext, JWSHeader> {
+
+ /** Constructor.*/
+ public IDTokenJOSEHeaderLookupStrategy() {
+ super();
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param strategy the AccessTokenResponseContext lookup strategy to use.
+ */
+ public IDTokenJOSEHeaderLookupStrategy(@Nonnull @ParameterName(name="accessTokenContextLookupStrategy")
+ final Function<ProfileRequestContext, AccessTokenResponseContext> strategy) {
+ super(strategy);
+ }
+
+ @Override
+ @Nullable public JWSHeader apply(@Nullable final ProfileRequestContext prc) {
+ final AccessTokenResponseContext tokenContext = getTokenResponseContextLookupStrategy().apply(prc);
+ final OIDCTokenResponse tokenResponse = tokenContext != null ? tokenContext.getTokenResponse() : null;
+ if (tokenResponse == null || tokenResponse.getOIDCTokens().getIDToken() == null) {
+ return null;
+ }
+ final Header header = tokenResponse.getOIDCTokens().getIDToken().getHeader();
+ if (header instanceof final JWSHeader jwsHeader) {
+ return jwsHeader;
+ }
+ return null;
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/OIDCProviderMetadataFromOuboundPeerLookupStrategy.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/OIDCProviderMetadataFromOuboundPeerLookupStrategy.java
new file mode 100644
index 00000000..725808a2
--- /dev/null
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/context/navigate/OIDCProviderMetadataFromOuboundPeerLookupStrategy.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.profile.context.navigate;
+
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.oidc.metadata.context.OIDCProviderMetadataContext;
+import net.shibboleth.oidc.profile.messaging.context.OIDCPeerEntityContext;
+
+/**
+ * Lookup function to extract the {@link OIDCProviderMetadataContext} from the {@link OIDCPeerEntityContext} in the
+ * outbound message.
+ */
+public class OIDCProviderMetadataFromOuboundPeerLookupStrategy
+ implements Function<ProfileRequestContext, OIDCProviderMetadataContext>{
+
+ @Override
+ @Nullable public OIDCProviderMetadataContext apply(@Nullable final ProfileRequestContext prc) {
+ if (prc == null) {
+ return null;
+ }
+ final MessageContext outboundMsgContext = prc.getOutboundMessageContext();
+ if (outboundMsgContext == null) {
+ return null;
+ }
+ final OIDCPeerEntityContext peerContext = outboundMsgContext.getSubcontext(OIDCPeerEntityContext.class);
+ if (peerContext == null) {
+ return null;
+ }
+ return peerContext.getSubcontext(OIDCProviderMetadataContext.class);
+ }
+
+}
diff --git a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OAuthAuthorizationRequest.java b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OAuthAuthorizationRequest.java
index 88a4b812..dc40caa2 100644
--- a/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OAuthAuthorizationRequest.java
+++ b/oidc-common-profile-api/src/main/java/net/shibboleth/oidc/profile/core/OAuthAuthorizationRequest.java
@@ -169,13 +169,24 @@ public class OAuthAuthorizationRequest {
}
/**
- * Set the state. Optional.
+ * Set the state token. Optional.
*
* @param theState The state to set.
*/
public void setState(@Nullable final StateToken theState) {
state = theState;
}
+
+ /**
+ * Set the state string component of the state token. Optional.
+ *
+ * @param theState The state to set.
+ */
+ public void setState(@Nullable final State theState) {
+ if (theState != null){
+ state = new StateToken(theState.getValue(), null);
+ }
+ }
/**
* Get the redirect_uri.
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list