[java-idp-oidc] branch main updated: Null cleanup of some parts of the impl-module.
Henri Mikkonen
henri.mikkonen at iki.fi
Thu Mar 28 10:46:43 UTC 2024
This is an automated email from the git hooks/post-receive script.
hjmikkon pushed a commit to branch main
in repository java-idp-oidc.
View the commit online:
http://git.shibboleth.net/view/?p=java-idp-oidc.git;a=commit;h=88151a8638ecd938cb3036cafd8a63fb02536b80
The following commit(s) were added to refs/heads/main by this push:
new 88151a86 Null cleanup of some parts of the impl-module.
88151a86 is described below
commit 88151a8638ecd938cb3036cafd8a63fb02536b80
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Mar 28 12:46:34 2024 +0200
Null cleanup of some parts of the impl-module.
---
.../impl/AlgorithmInfoMetadataValueResolver.java | 13 ++-
.../metadata/impl/ArrayMetadataValueResolver.java | 2 +-
.../impl/CredentialMetadataValueResolver.java | 88 ++++++++-------
.../DynamicFilesystemProviderMetadataResolver.java | 13 ++-
.../impl/FilesystemMetadataValueResolver.java | 11 +-
.../impl/FilesystemProviderMetadataResolver.java | 40 ++++---
.../impl/FunctionMetadataValueResolver.java | 14 ++-
.../decoding/impl/BaseOAuth2RequestDecoder.java | 6 +-
.../impl/OAuth2AuthorizationRequestDecoder.java | 2 +-
.../impl/OAuth2IntrospectionRequestDecoder.java | 9 +-
.../impl/OAuth2RevocationRequestDecoder.java | 2 +-
.../impl/PopulateOIDCMetadataContext.java | 21 +++-
.../impl/SetEntityIdToSAMLPeerEntityContext.java | 2 +-
.../AbstractOAuthAuthorizationRequestAction.java | 7 --
.../AbstractOAuthAuthorizationResponseAction.java | 14 ++-
.../profile/impl/AbstractProcessTokenAction.java | 27 ++++-
.../op/oauth2/profile/impl/BuildAccessToken.java | 122 +++++++++++++++------
.../BuildRevokeTokenErrorResponseFromEvent.java | 4 +-
.../FormOutboundIntrospectionResponseMessage.java | 11 +-
.../FormOutboundRevokeTokenResponseMessage.java | 2 +-
.../oidc/op/oauth2/profile/impl/RevokeToken.java | 9 +-
.../impl/SetAccessTokenToResponseContext.java | 43 ++++++--
.../SetAuthorizationCodeToResponseContext.java | 66 ++++++++---
.../impl/SetRequestObjectToResponseContext.java | 46 +++++---
.../op/oauth2/profile/impl/ValidateAudience.java | 27 +++--
.../impl/ValidateAuthorizationRequestType.java | 2 +-
.../impl/ValidateClientIDAgainstPolicy.java | 22 ++--
.../oauth2/profile/impl/ValidateCodeChallenge.java | 9 +-
.../oauth2/profile/impl/ValidateRedirectURI.java | 28 +++--
.../oauth2/profile/impl/ValidateRequestObject.java | 56 ++++------
.../oauth2/profile/impl/ValidateResponseType.java | 33 ++++--
.../oidc/op/oauth2/profile/impl/ValidateScope.java | 31 ++++--
.../impl/AbstractBuildErrorResponseFromEvent.java | 5 +-
33 files changed, 503 insertions(+), 284 deletions(-)
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/AlgorithmInfoMetadataValueResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/AlgorithmInfoMetadataValueResolver.java
index 23a04755..6180dad4 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/AlgorithmInfoMetadataValueResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/AlgorithmInfoMetadataValueResolver.java
@@ -28,15 +28,16 @@ import org.opensaml.security.config.SecurityConfiguration;
import org.opensaml.xmlsec.AlgorithmPolicyConfiguration;
import org.opensaml.xmlsec.algorithm.AlgorithmSupport;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import net.shibboleth.idp.plugin.oidc.op.metadata.resolver.MetadataValueResolver;
import net.shibboleth.oidc.profile.config.JSONSecurityConfiguration;
import net.shibboleth.oidc.security.jose.EncryptionConfiguration;
import net.shibboleth.oidc.security.jose.SignatureSigningConfiguration;
+import net.shibboleth.profile.config.ProfileConfiguration;
import net.shibboleth.profile.context.RelyingPartyContext;
import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.resolver.ResolverException;
/**
@@ -47,7 +48,7 @@ public class AlgorithmInfoMetadataValueResolver extends AbstractIdentifiableInit
implements MetadataValueResolver {
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(AlgorithmInfoMetadataValueResolver.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(AlgorithmInfoMetadataValueResolver.class);
/**
* Strategy used to locate the {@link RelyingPartyContext} associated with a given {@link ProfileRequestContext}.
@@ -116,9 +117,11 @@ public class AlgorithmInfoMetadataValueResolver extends AbstractIdentifiableInit
log.warn("Could not find profile configuration, nothing to do");
return result;
}
-
+
+ final ProfileConfiguration profileConfig = rpCtx.getProfileConfig();
+ assert profileConfig != null;
final SecurityConfiguration securityConfig =
- rpCtx.getProfileConfig().getSecurityConfiguration(profileRequestContext);
+ profileConfig.getSecurityConfiguration(profileRequestContext);
if (securityConfig == null) {
log.warn("Could not find security configuration, nothing to do");
return result;
@@ -163,7 +166,7 @@ public class AlgorithmInfoMetadataValueResolver extends AbstractIdentifiableInit
protected void populateAlgorithmsAgainstPolicy(final List<String> algorithms, final List<String> candidates,
final AlgorithmPolicyConfiguration policy) {
for (final String candidate : candidates) {
- if (!AlgorithmSupport.validateAlgorithmURI(candidate,
+ if (candidate != null && !AlgorithmSupport.validateAlgorithmURI(candidate,
policy.getIncludedAlgorithms(),
policy.getExcludedAlgorithms())) {
log.debug("Algorithm failed include/exclude validation: {}", candidate);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/ArrayMetadataValueResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/ArrayMetadataValueResolver.java
index 3e2a7a5a..aca0d242 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/ArrayMetadataValueResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/ArrayMetadataValueResolver.java
@@ -23,7 +23,6 @@ import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
@@ -31,6 +30,7 @@ import net.shibboleth.idp.plugin.oidc.op.metadata.resolver.MetadataValueResolver
import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
import net.shibboleth.shared.resolver.ResolverException;
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/CredentialMetadataValueResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/CredentialMetadataValueResolver.java
index bbbc9e94..9e7a7d04 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/CredentialMetadataValueResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/CredentialMetadataValueResolver.java
@@ -23,13 +23,14 @@ import java.util.List;
import java.util.function.Function;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.security.config.SecurityConfiguration;
import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.UsageType;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.jose.jwk.Curve;
import com.nimbusds.jose.jwk.ECKey;
@@ -41,10 +42,13 @@ import net.minidev.json.JSONArray;
import net.shibboleth.idp.plugin.oidc.op.metadata.resolver.MetadataValueResolver;
import net.shibboleth.oidc.profile.config.JSONSecurityConfiguration;
import net.shibboleth.oidc.security.credential.JWKCredential;
+import net.shibboleth.oidc.security.jose.SignatureSigningConfiguration;
+import net.shibboleth.profile.config.ProfileConfiguration;
import net.shibboleth.profile.context.RelyingPartyContext;
import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.resolver.ResolverException;
/**
@@ -55,7 +59,7 @@ public class CredentialMetadataValueResolver extends AbstractIdentifiableInitial
implements MetadataValueResolver {
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(CredentialMetadataValueResolver.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(CredentialMetadataValueResolver.class);
/**
* Strategy used to locate the {@link RelyingPartyContext} associated with a given {@link ProfileRequestContext}.
@@ -96,15 +100,20 @@ public class CredentialMetadataValueResolver extends AbstractIdentifiableInitial
final PublicKey publicKey = credential.getPublicKey();
final String kid = credential instanceof JWKCredential ? ((JWKCredential) credential).getKid() : null;
final KeyUse use;
- switch (credential.getUsageType()) {
- case SIGNING:
- use = KeyUse.SIGNATURE;
- break;
- case ENCRYPTION:
- use = KeyUse.ENCRYPTION;
- break;
- default:
- use = null;
+ final UsageType usageType = credential.getUsageType();
+ if (usageType != null) {
+ switch (usageType) {
+ case SIGNING:
+ use = KeyUse.SIGNATURE;
+ break;
+ case ENCRYPTION:
+ use = KeyUse.ENCRYPTION;
+ break;
+ default:
+ use = null;
+ }
+ } else {
+ use = null;
}
final JWK jwk;
if (publicKey instanceof RSAPublicKey) {
@@ -122,7 +131,7 @@ public class CredentialMetadataValueResolver extends AbstractIdentifiableInitial
jwk = builder.build();
} else {
// TODO: support other algorithms
- log.warn("Unsupported public key {}", publicKey.getAlgorithm());
+ log.warn("Unsupported public key {}", publicKey == null ? null : publicKey.getAlgorithm());
throw new ConstraintViolationException("Unsupported public key algorithm");
}
return jwk;
@@ -138,44 +147,45 @@ public class CredentialMetadataValueResolver extends AbstractIdentifiableInitial
log.warn("Could not find profile configuration, nothing to do");
return result;
}
-
- final SecurityConfiguration securityConfig =
- rpCtx.getProfileConfig().getSecurityConfiguration(profileRequestContext);
- if (securityConfig == null) {
- log.warn("Could not find security configuration, nothing to do");
- return result;
- }
+ final ProfileConfiguration profileConfig = rpCtx.getProfileConfig();
+ assert profileConfig != null;
- if (!(securityConfig instanceof JSONSecurityConfiguration)) {
- log.warn("Security configuration class was not expected: {}", securityConfig);
- return result;
- }
- final JSONSecurityConfiguration jsonSecurityConfig = (JSONSecurityConfiguration) securityConfig;
+ final SecurityConfiguration securityConfig = profileConfig.getSecurityConfiguration(profileRequestContext);
- if (jsonSecurityConfig.getJwtSignatureSigningConfiguration() == null) {
- log.warn("Could not find signing configuration, nothing to do");
- return result;
- }
+ if (securityConfig instanceof JSONSecurityConfiguration jsonSecurityConfig) {
+ final SignatureSigningConfiguration jwtSignatureSigningConfiguration =
+ jsonSecurityConfig.getJwtSignatureSigningConfiguration();
+ if (jwtSignatureSigningConfiguration == null) {
+ log.warn("Could not find signing configuration, nothing to do");
+ return result;
+ }
- // currently only signing keys are included
- final List<Credential> credentials =
- jsonSecurityConfig.getJwtSignatureSigningConfiguration().getSigningCredentials();
- final JSONArray jwkCredentials = new JSONArray();
- for (final Credential credential : credentials) {
- try {
- jwkCredentials.add(parseJwkCredential(credential).toJSONObject());
- } catch (final ConstraintViolationException e) {
- log.warn("Ignoring key from the resulting list", e);
+ // currently only signing keys are included
+ final List<Credential> credentials = jwtSignatureSigningConfiguration.getSigningCredentials();
+ final JSONArray jwkCredentials = new JSONArray();
+ for (final Credential credential : credentials) {
+ assert credential != null;
+ try {
+ jwkCredentials.add(parseJwkCredential(credential).toJSONObject());
+ } catch (final ConstraintViolationException e) {
+ log.warn("Ignoring key from the resulting list", e);
+ }
}
+ result.add(jwkCredentials);
+ return result;
+ }
+ if (securityConfig == null) {
+ log.warn("Could not find security configuration, nothing to do");
+ } else {
+ log.warn("Security configuration class was not expected: {}", securityConfig);
}
- result.add(jwkCredentials);
return result;
}
/** {@inheritDoc} */
@Override
- public Object resolveSingle(@Nonnull final ProfileRequestContext profileRequestContext) throws ResolverException {
+ public Object resolveSingle(@Nullable final ProfileRequestContext profileRequestContext) throws ResolverException {
final Iterator<Object> iterator = resolve(profileRequestContext).iterator();
if (iterator.hasNext()) {
return iterator.next();
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/DynamicFilesystemProviderMetadataResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/DynamicFilesystemProviderMetadataResolver.java
index e24c5451..938c7d49 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/DynamicFilesystemProviderMetadataResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/DynamicFilesystemProviderMetadataResolver.java
@@ -28,7 +28,6 @@ import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import com.nimbusds.oauth2.sdk.ParseException;
@@ -38,6 +37,7 @@ import net.minidev.json.JSONObject;
import net.shibboleth.idp.plugin.oidc.op.metadata.resolver.MetadataValueResolver;
import net.shibboleth.idp.plugin.oidc.op.metadata.resolver.RefreshableMetadataValueResolver;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.resolver.ResolverException;
/**
@@ -47,7 +47,7 @@ import net.shibboleth.shared.resolver.ResolverException;
public class DynamicFilesystemProviderMetadataResolver extends FilesystemProviderMetadataResolver {
/** Class logger. */
- private final Logger log = LoggerFactory.getLogger(DynamicFilesystemProviderMetadataResolver.class);
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DynamicFilesystemProviderMetadataResolver.class);
/** The map of dynamic metadata value resolvers, key corresponding to the name of the metadata field. */
private Map<String, ? extends MetadataValueResolver> dynamicResolvers = new HashMap<>();
@@ -128,12 +128,13 @@ public class DynamicFilesystemProviderMetadataResolver extends FilesystemProvide
final Instant updateTime = super.getMetadataUpdateTime();
for (final String id : dynamicResolvers.keySet()) {
final MetadataValueResolver resolver = dynamicResolvers.get(id);
- if (resolver instanceof RefreshableMetadataValueResolver) {
- if (((RefreshableMetadataValueResolver) resolver).getLastUpdate() == null) {
+ if (resolver instanceof RefreshableMetadataValueResolver refreshableResolver) {
+ if (refreshableResolver.getLastUpdate() == null) {
return Instant.now();
}
- if (((RefreshableMetadataValueResolver) resolver).getLastUpdate().isAfter(updateTime)) {
- return ((RefreshableMetadataValueResolver) resolver).getLastUpdate();
+ final Instant lastUpdate = refreshableResolver.getLastUpdate();
+ if (lastUpdate != null && lastUpdate.isAfter(updateTime)) {
+ return refreshableResolver.getLastUpdate();
}
}
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FilesystemMetadataValueResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FilesystemMetadataValueResolver.java
index 867d0d77..8fcdfc91 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FilesystemMetadataValueResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FilesystemMetadataValueResolver.java
@@ -30,6 +30,7 @@ import com.nimbusds.oauth2.sdk.id.Identifier;
import net.minidev.json.JSONValue;
import net.shibboleth.idp.plugin.oidc.op.metadata.resolver.RefreshableMetadataValueResolver;
import net.shibboleth.oidc.metadata.impl.AbstractFileOIDCEntityResolver;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.resolver.ResolverException;
/**
@@ -72,7 +73,7 @@ public class FilesystemMetadataValueResolver extends AbstractFileOIDCEntityResol
* @throws ResolverException thrown if there is an error during resolution.
*/
@Override
- @Nullable public Iterable<Object> resolve(@Nullable final ProfileRequestContext profileRequestContext)
+ @Nonnull public Iterable<Object> resolve(@Nullable final ProfileRequestContext profileRequestContext)
throws ResolverException {
ifNotInitializedThrowUninitializedComponentException();
ifDestroyedThrowDestroyedComponentException();
@@ -96,9 +97,13 @@ public class FilesystemMetadataValueResolver extends AbstractFileOIDCEntityResol
}
/** {@inheritDoc} */
- @Override
+ @Override @Nonnull
protected List<Object> parse(final byte[] bytes) throws ParseException {
- return List.of(JSONValue.parse(bytes));
+ final Object json = JSONValue.parse(bytes);
+ if (json == null) {
+ throw new ParseException("Could not parse JSON object from the bytes");
+ }
+ return CollectionSupport.listOf(json);
}
/** {@inheritDoc} */
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FilesystemProviderMetadataResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FilesystemProviderMetadataResolver.java
index 54e437ae..414c1c1b 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FilesystemProviderMetadataResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FilesystemProviderMetadataResolver.java
@@ -27,7 +27,6 @@ import javax.annotation.Nullable;
import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import com.nimbusds.oauth2.sdk.ParseException;
@@ -39,7 +38,10 @@ import net.shibboleth.idp.plugin.oidc.op.metadata.resolver.RefreshableProviderMe
import net.shibboleth.oidc.metadata.impl.AbstractFileOIDCEntityResolver;
import net.shibboleth.profile.config.OverriddenIssuerProfileConfiguration;
import net.shibboleth.profile.context.RelyingPartyContext;
+import net.shibboleth.profile.relyingparty.RelyingPartyConfiguration;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.resolver.ResolverException;
/**
@@ -99,7 +101,7 @@ public class FilesystemProviderMetadataResolver extends AbstractFileOIDCEntityRe
/** {@inheritDoc} */
@Override
- @Nullable public Iterable<OIDCProviderMetadata> resolve(@Nullable final ProfileRequestContext profileRequestContext)
+ @Nonnull public Iterable<OIDCProviderMetadata> resolve(@Nullable final ProfileRequestContext profileRequestContext)
throws ResolverException {
ifNotInitializedThrowUninitializedComponentException();
ifDestroyedThrowDestroyedComponentException();
@@ -112,20 +114,24 @@ public class FilesystemProviderMetadataResolver extends AbstractFileOIDCEntityRe
}
String responderId = null;
- if (rpCtx.getProfileConfig() instanceof OverriddenIssuerProfileConfiguration) {
- responderId =
- ((OverriddenIssuerProfileConfiguration) rpCtx.getProfileConfig()).getIssuer(profileRequestContext);
+ if (rpCtx.getProfileConfig() instanceof OverriddenIssuerProfileConfiguration overriddenIssuerProfileConfig) {
+ responderId = overriddenIssuerProfileConfig.getIssuer(profileRequestContext);
}
if (responderId == null) {
- responderId = rpCtx.getConfiguration().getIssuer(profileRequestContext);
+ final RelyingPartyConfiguration rpConfig = rpCtx.getConfiguration();
+ if (rpConfig != null) {
+ responderId = rpConfig.getIssuer(profileRequestContext);
+ }
}
final String issuer = responderId;
- return entities
+ final List<OIDCProviderMetadata> result = entities
.stream()
.filter(e -> e.getIssuer().getValue().equals(issuer))
.collect(Collectors.toUnmodifiableList());
+ assert result != null;
+ return result;
}
/** {@inheritDoc} */
@@ -133,25 +139,27 @@ public class FilesystemProviderMetadataResolver extends AbstractFileOIDCEntityRe
@Nullable public OIDCProviderMetadata resolveSingle(@Nullable final ProfileRequestContext profileRequestContext)
throws ResolverException {
final Iterable<OIDCProviderMetadata> iterable = resolve(profileRequestContext);
- if (iterable != null) {
- final Iterator<OIDCProviderMetadata> iterator = iterable.iterator();
- if (iterator != null && iterator.hasNext()) {
- return iterator.next();
- }
+ final Iterator<OIDCProviderMetadata> iterator = iterable.iterator();
+ if (iterator != null && iterator.hasNext()) {
+ return iterator.next();
}
log.warn("Could not find any clients with the given criteria");
return null;
}
/** {@inheritDoc} */
- @Override
+ @Override @Nonnull
protected List<OIDCProviderMetadata> parse(final byte[] bytes) throws ParseException {
- return List.of(OIDCProviderMetadata.parse(JSONObjectUtils.parse(new String(bytes))));
+ final OIDCProviderMetadata metadata = OIDCProviderMetadata.parse(JSONObjectUtils.parse(new String(bytes)));
+ assert metadata != null;
+ return CollectionSupport.listOf(metadata);
}
/** {@inheritDoc} */
- @Override
+ @Override @Nonnull
protected Issuer getKey(@Nonnull final OIDCProviderMetadata value) {
- return value.getIssuer();
+ final Issuer issuer = value.getIssuer();
+ assert issuer != null;
+ return issuer;
}
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FunctionMetadataValueResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FunctionMetadataValueResolver.java
index 31c5f44e..5422dc91 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FunctionMetadataValueResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/metadata/impl/FunctionMetadataValueResolver.java
@@ -14,15 +14,16 @@
package net.shibboleth.idp.plugin.oidc.op.metadata.impl;
-import java.util.List;
import java.util.function.Function;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opensaml.profile.context.ProfileRequestContext;
import net.shibboleth.idp.plugin.oidc.op.metadata.resolver.MetadataValueResolver;
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
@@ -66,14 +67,15 @@ public class FunctionMetadataValueResolver extends AbstractIdentifiableInitializ
}
/** {@inheritDoc} */
- @Override
- public Iterable<Object> resolve(@Nonnull final ProfileRequestContext criteria) throws ResolverException {
- return List.of(resolveSingle(criteria));
+ @Override @Nonnull
+ public Iterable<Object> resolve(@Nullable final ProfileRequestContext criteria) throws ResolverException {
+ final Object result = resolveSingle(criteria);
+ return result == null ? CollectionSupport.emptyList() : CollectionSupport.listOf(result);
}
/** {@inheritDoc} */
- @Override
- public Object resolveSingle(@Nonnull final ProfileRequestContext criteria) throws ResolverException {
+ @Override @Nullable
+ public Object resolveSingle(@Nullable final ProfileRequestContext criteria) throws ResolverException {
return resolverFunction.apply(criteria);
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/BaseOAuth2RequestDecoder.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/BaseOAuth2RequestDecoder.java
index ad558511..9cf747da 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/BaseOAuth2RequestDecoder.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/BaseOAuth2RequestDecoder.java
@@ -27,12 +27,13 @@ import org.opensaml.messaging.context.MessageContext;
import org.opensaml.messaging.decoder.MessageDecodingException;
import org.opensaml.messaging.decoder.servlet.AbstractHttpServletRequestMessageDecoder;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.oauth2.sdk.Request;
import com.nimbusds.oauth2.sdk.http.HTTPRequest;
+import jakarta.servlet.http.HttpServletRequest;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequestAudienceLookupFunction;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Base decoder for Nimbus OAuth2 request messages.
@@ -108,7 +109,8 @@ public abstract class BaseOAuth2RequestDecoder<T extends Request> extends Abstra
*/
@Nullable protected String getEndpointURI(final T message) {
if (removeIpAddressFromEndpointUri) {
- return getHttpServletRequest().getRequestURI();
+ final HttpServletRequest httpServletRequest = getHttpServletRequest();
+ return httpServletRequest != null ? httpServletRequest.getRequestURI() : null;
} else {
final URI endpointUri = message.getEndpointURI();
return endpointUri != null ? endpointUri.toString() : null;
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2AuthorizationRequestDecoder.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2AuthorizationRequestDecoder.java
index 31a0c28b..d85ccd1c 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2AuthorizationRequestDecoder.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2AuthorizationRequestDecoder.java
@@ -21,7 +21,6 @@ import javax.annotation.Nullable;
import org.opensaml.messaging.decoder.MessageDecodingException;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
import com.nimbusds.oauth2.sdk.AuthorizationRequest;
@@ -29,6 +28,7 @@ import com.nimbusds.oauth2.sdk.http.HTTPRequest;
import com.nimbusds.oauth2.sdk.http.JakartaServletUtils;
import net.shibboleth.idp.plugin.oidc.op.decoding.impl.RequestUtil;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Message decoder decoding OAuth2 {@link AuthorizationRequest}s.
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2IntrospectionRequestDecoder.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2IntrospectionRequestDecoder.java
index 5f9a6625..0288aeb5 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2IntrospectionRequestDecoder.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2IntrospectionRequestDecoder.java
@@ -20,14 +20,15 @@ import javax.annotation.Nullable;
import org.opensaml.messaging.decoder.MessageDecodingException;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
import com.nimbusds.oauth2.sdk.TokenIntrospectionRequest;
import com.nimbusds.oauth2.sdk.http.HTTPRequest;
import com.nimbusds.oauth2.sdk.http.JakartaServletUtils;
+import jakarta.servlet.http.HttpServletRequest;
import net.shibboleth.idp.plugin.oidc.op.decoding.impl.RequestUtil;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
/**
@@ -43,14 +44,16 @@ public class OAuth2IntrospectionRequestDecoder extends BaseOAuth2RequestDecoder<
@Override
protected TokenIntrospectionRequest parseMessage() throws MessageDecodingException {
try {
- final String query = StringSupport.trimOrNull(getHttpServletRequest().getQueryString());
+ final HttpServletRequest httpServletRequest = getHttpServletRequest();
+ final String query = httpServletRequest != null ?
+ StringSupport.trimOrNull(httpServletRequest.getQueryString()) : null;
// the spec mandates token to be sent in application/x-www-form-urlencoded data
// Nimbus allows the use of query parameters too, so we deny it by ourselves
if (query != null && query.contains("token=")) {
log.error("The query parameters contain 'token'");
throw new MessageDecodingException("The query parameters contain 'token'");
}
- final HTTPRequest httpReq = JakartaServletUtils.createHTTPRequest(getHttpServletRequest());
+ final HTTPRequest httpReq = JakartaServletUtils.createHTTPRequest(httpServletRequest);
getProtocolMessageLogger().trace("Inbound request {}", RequestUtil.toString(httpReq));
return TokenIntrospectionRequest.parse(httpReq);
} catch (final com.nimbusds.oauth2.sdk.ParseException | IOException e) {
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2RevocationRequestDecoder.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2RevocationRequestDecoder.java
index d3d4031b..9f48e497 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2RevocationRequestDecoder.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/decoding/impl/OAuth2RevocationRequestDecoder.java
@@ -20,7 +20,6 @@ import javax.annotation.Nullable;
import org.opensaml.messaging.decoder.MessageDecodingException;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.google.common.base.MoreObjects;
import com.nimbusds.oauth2.sdk.TokenRevocationRequest;
@@ -28,6 +27,7 @@ import com.nimbusds.oauth2.sdk.http.HTTPRequest;
import com.nimbusds.oauth2.sdk.http.JakartaServletUtils;
import net.shibboleth.idp.plugin.oidc.op.decoding.impl.RequestUtil;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Message decoder decoding OpenID Connect {@link TokenRevocationRequest}s.
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/messaging/impl/PopulateOIDCMetadataContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/messaging/impl/PopulateOIDCMetadataContext.java
index 251442f9..9accf50d 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/messaging/impl/PopulateOIDCMetadataContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/messaging/impl/PopulateOIDCMetadataContext.java
@@ -24,15 +24,16 @@ import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.opensaml.messaging.handler.AbstractMessageHandler;
import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml.saml2.metadata.RoleDescriptor;
import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* A message handler that attempts to locate OIDC client information from the SAML entity descriptor containing role
@@ -52,8 +53,11 @@ public class PopulateOIDCMetadataContext extends AbstractMessageHandler {
* Constructor.
*/
public PopulateOIDCMetadataContext() {
- samlMetadataContextLookupStrategy = new ChildContextLookup<>(SAMLMetadataContext.class).compose(
- new ChildContextLookup<>(SAMLPeerEntityContext.class));
+ final Function<MessageContext,SAMLMetadataContext> smcls =
+ new ChildContextLookup<>(SAMLMetadataContext.class).compose(
+ new ChildContextLookup<>(SAMLPeerEntityContext.class));
+ assert smcls != null;
+ samlMetadataContextLookupStrategy = smcls;
}
/**
@@ -79,13 +83,18 @@ public class PopulateOIDCMetadataContext extends AbstractMessageHandler {
return;
}
- final List<RoleDescriptor> roleDescriptors
- = samlMetadataCtx.getEntityDescriptor().getRoleDescriptors(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
+ final EntityDescriptor entityDescriptor = samlMetadataCtx.getEntityDescriptor();
+ if (entityDescriptor == null) {
+ log.error("Unable to locate EntityDescriptor");
+ return;
+ }
+ final List<RoleDescriptor> roleDescriptors =
+ entityDescriptor.getRoleDescriptors(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
for (final RoleDescriptor roleDescriptor : roleDescriptors) {
if (roleDescriptor instanceof SPSSODescriptor) {
final List<OIDCClientInformation> clientInformations
= roleDescriptor.getObjectMetadata().get(OIDCClientInformation.class);
- if (clientInformations != null && clientInformations.size() > 0) {
+ if (clientInformations.size() > 0) {
final OIDCMetadataContext oidcCtx = new OIDCMetadataContext();
oidcCtx.setClientInformation(clientInformations.get(0));
messageContext.addSubcontext(oidcCtx);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/messaging/impl/SetEntityIdToSAMLPeerEntityContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/messaging/impl/SetEntityIdToSAMLPeerEntityContext.java
index aae8456b..037d4e95 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/messaging/impl/SetEntityIdToSAMLPeerEntityContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/messaging/impl/SetEntityIdToSAMLPeerEntityContext.java
@@ -25,12 +25,12 @@ import org.opensaml.messaging.handler.MessageHandlerException;
import org.opensaml.saml.common.messaging.context.AbstractSAMLEntityContext;
import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.oauth2.sdk.id.ClientID;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultClientIDLookupFunction;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* {@link MessageHandler} that sets the entityID to the given {@link SAMLPeerEntityContext} class.
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractOAuthAuthorizationRequestAction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractOAuthAuthorizationRequestAction.java
index 8e1d5223..2791dbfb 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractOAuthAuthorizationRequestAction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractOAuthAuthorizationRequestAction.java
@@ -14,11 +14,8 @@
package net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl;
-import javax.annotation.Nonnull;
import org.opensaml.messaging.context.MessageContext;
import org.opensaml.profile.context.ProfileRequestContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.oauth2.sdk.AuthorizationRequest;
@@ -30,10 +27,6 @@ import net.shibboleth.idp.plugin.oidc.op.profile.impl.AbstractOIDCRequestAction;
*/
public abstract class AbstractOAuthAuthorizationRequestAction extends AbstractOIDCRequestAction<AuthorizationRequest> {
- /** Class logger. */
- @Nonnull
- private Logger log = LoggerFactory.getLogger(AbstractOAuthAuthorizationRequestAction.class);
-
/**
* Returns OAuth authorization request.
*
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractOAuthAuthorizationResponseAction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractOAuthAuthorizationResponseAction.java
index 1ca637e0..511257d0 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractOAuthAuthorizationResponseAction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractOAuthAuthorizationResponseAction.java
@@ -15,18 +15,19 @@
package net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opensaml.messaging.context.MessageContext;
import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.oauth2.sdk.AuthorizationRequest;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
*
@@ -41,11 +42,11 @@ public abstract class AbstractOAuthAuthorizationResponseAction extends AbstractO
private Logger log = LoggerFactory.getLogger(AbstractOAuthAuthorizationResponseAction.class);
/** oidc response context. */
- @Nonnull
+ @Nullable
private OIDCAuthenticationResponseContext oidcResponseContext;
/** OIDC Metadata context. */
- @Nonnull
+ @Nullable
private OIDCMetadataContext oidcMetadataContext;
/**
@@ -53,7 +54,7 @@ public abstract class AbstractOAuthAuthorizationResponseAction extends AbstractO
*
* @return ctx.
*/
- @Nonnull
+ @Nullable
public OIDCAuthenticationResponseContext getOidcResponseContext() {
return oidcResponseContext;
}
@@ -63,7 +64,7 @@ public abstract class AbstractOAuthAuthorizationResponseAction extends AbstractO
*
* @return The OIDC Metadata context.
*/
- public OIDCMetadataContext getMetadataContext() {
+ @Nullable public OIDCMetadataContext getMetadataContext() {
return oidcMetadataContext;
}
@@ -88,7 +89,8 @@ public abstract class AbstractOAuthAuthorizationResponseAction extends AbstractO
return false;
}
- oidcMetadataContext = profileRequestContext.getInboundMessageContext().getSubcontext(OIDCMetadataContext.class);
+ oidcMetadataContext =
+ profileRequestContext.ensureInboundMessageContext().getSubcontext(OIDCMetadataContext.class);
return true;
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractProcessTokenAction.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractProcessTokenAction.java
index e56f8692..48ffba49 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractProcessTokenAction.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/AbstractProcessTokenAction.java
@@ -32,7 +32,6 @@ import org.opensaml.security.credential.CredentialResolver;
import org.opensaml.security.credential.UsageType;
import org.opensaml.security.criteria.UsageCriterion;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jwt.JWTClaimsSet;
@@ -52,9 +51,12 @@ import net.shibboleth.oidc.jwt.claims.JWTValidationException;
import net.shibboleth.oidc.profile.config.navigate.IssuedClaimsValidatorLookupFunction;
import net.shibboleth.oidc.profile.core.OidcEventIds;
import net.shibboleth.oidc.security.impl.JWTSignatureValidationUtil;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.resolver.CriteriaSet;
import net.shibboleth.shared.resolver.ResolverException;
import net.shibboleth.shared.security.DataSealer;
@@ -90,7 +92,7 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
@Nullable private ClaimsValidator claimsValidator;
/** Source of signing keys. */
- @Nullable private CredentialResolver credentialResolver;
+ @NonnullAfterInit private CredentialResolver credentialResolver;
/** List of deserializer bi-functions for refresh tokens to be used in addition to unsealing opaque value. */
@Nonnull private List<BiFunction<ProfileRequestContext,String,RefreshTokenClaimsSet>> refreshTokenDeserializers;
@@ -147,6 +149,16 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
Constraint.isNotNull(deserializers, "List of refresh token deserializers cannot be null");
}
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (credentialResolver == null) {
+ throw new ComponentInitializationException("Credential resolver cannot be null");
+ }
+ }
+
/** {@inheritDoc} */
@Override
protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -196,6 +208,7 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
}
log.debug("{} Validating parsed/decoded claims set: {}", getLogPrefix(), tokenClaimsSet.toString());
+ assert claimsValidator != null;
try {
claimsValidator.validate(tokenClaimsSet, profileRequestContext);
} catch (final JWTValidationException e) {
@@ -204,7 +217,7 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
}
// Populate outbound tree.
- profileRequestContext.getOutboundMessageContext().getSubcontext(
+ profileRequestContext.ensureOutboundMessageContext().ensureSubcontext(
OAuth2TokenMgmtResponseContext.class).setTokenClaimsSet(tokenClaimsSet);
}
// Checkstyle: CyclomaticComplexity ON
@@ -230,6 +243,7 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
return null;
}
+ assert signedJWT != null;
final JWTClaimsSet jwtClaimsSet = signedJWT.getJWTClaimsSet();
log.debug("{} Checking JWT signature", getLogPrefix());
final Collection<Credential> credList = new ArrayList<>();
@@ -242,6 +256,7 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
return null;
}
+ assert signedJWT != null;
final String errorEventId = JWTSignatureValidationUtil.validateSignatureEx(credList, signedJWT,
OidcEventIds.INVALID_GRANT);
if (errorEventId != null) {
@@ -260,7 +275,10 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
// Fall back to opaque.
try {
- return AccessTokenClaimsSet.parse(token.getValue(), dataSealer).getClaimsSet();
+ final String tokenValue = token.getValue();
+ assert tokenValue != null;
+ assert dataSealer != null;
+ return AccessTokenClaimsSet.parse(tokenValue, dataSealer).getClaimsSet();
} catch (final DataSealerException | ParseException e) {
}
@@ -279,6 +297,7 @@ public abstract class AbstractProcessTokenAction<T> extends AbstractOIDCRequestA
@Nonnull @NotEmpty final Token token) {
final String refreshToken = token.getValue();
try {
+ assert refreshToken != null;
assert dataSealer != null;
return RefreshTokenClaimsSet.parse(refreshToken, dataSealer).getClaimsSet();
} catch (ParseException | DataSealerException e) {
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/BuildAccessToken.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/BuildAccessToken.java
index bb304a64..abfec090 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/BuildAccessToken.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/BuildAccessToken.java
@@ -31,7 +31,6 @@ import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.PlainJWT;
@@ -41,6 +40,7 @@ import com.nimbusds.openid.connect.sdk.AuthenticationRequest;
import com.nimbusds.openid.connect.sdk.claims.ClaimsSet;
import net.minidev.json.JSONArray;
+import net.minidev.json.JSONObject;
import net.shibboleth.idp.authn.context.SubjectContext;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.AccessTokenContext;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseConsentContext;
@@ -64,6 +64,7 @@ import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.logic.FunctionSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
import net.shibboleth.shared.security.DataSealer;
import net.shibboleth.shared.security.DataSealerException;
@@ -170,20 +171,29 @@ public class BuildAccessToken extends AbstractOIDCResponseAction {
new InboundMessageContextLookup());
idGeneratorLookupStrategy = FunctionSupport.constant(new SecureRandomIdentifierGenerationStrategy());
-
- tokenClaimsContextLookupStrategy =
+
+ final Function<ProfileRequestContext,OIDCAuthenticationResponseTokenClaimsContext> tccls =
new ChildContextLookup<>(OIDCAuthenticationResponseTokenClaimsContext.class).compose(
new OIDCAuthenticationResponseContextLookupFunction());
- consentContextLookupStrategy =
+ assert tccls != null;
+ tokenClaimsContextLookupStrategy = tccls;
+
+ final Function<ProfileRequestContext, OIDCAuthenticationResponseConsentContext> ccls =
new ChildContextLookup<>(OIDCAuthenticationResponseConsentContext.class).compose(
new OIDCAuthenticationResponseContextLookupFunction());
+ assert ccls != null;
+ consentContextLookupStrategy = ccls;
consentEnabledPredicate = new AttributeConsentFlowEnabledPredicate();
// PRC -> inbound message context -> OIDC response context -> ATC
- accessTokenContextCreationStrategy = new ChildContextLookup<>(AccessTokenContext.class, true).compose(
- new ChildContextLookup<>(OIDCAuthenticationResponseContext.class).compose(
- new OutboundMessageContextLookup()));
+ final Function<ProfileRequestContext,AccessTokenContext> atccs =
+ new ChildContextLookup<>(AccessTokenContext.class, true).compose(
+ new ChildContextLookup<>(OIDCAuthenticationResponseContext.class).compose(
+ new OutboundMessageContextLookup()));
+ assert atccs != null;
+ accessTokenContextCreationStrategy = atccs;
+
tokenClaimsSetManipulationStrategyLookupStrategy =
new AccessTokenClaimsSetManipulationStrategyLookupFunction();
xmlSafeIdentifier = true;
@@ -366,7 +376,7 @@ public class BuildAccessToken extends AbstractOIDCResponseAction {
if (tokenClaimsSet != null && !(tokenClaimsSet instanceof RefreshTokenClaimsSet)
&& !(tokenClaimsSet instanceof AuthorizeCodeClaimsSet)) {
log.error("{} Authorization grant is of unknown type: {}", getLogPrefix(),
- tokenClaimsSet.getClass().getName());
+ tokenClaimsSet != null ? tokenClaimsSet.getClass().getName() : null);
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
return false;
}
@@ -393,9 +403,9 @@ public class BuildAccessToken extends AbstractOIDCResponseAction {
}
if (profileRequestContext.getInboundMessageContext() != null
- && profileRequestContext.getInboundMessageContext().getMessage() instanceof AuthenticationRequest) {
- authenticationRequest =
- (AuthenticationRequest) profileRequestContext.getInboundMessageContext().getMessage();
+ && profileRequestContext.ensureInboundMessageContext().getMessage()
+ instanceof AuthenticationRequest authnRequest) {
+ authenticationRequest = authnRequest;
}
}
@@ -412,6 +422,7 @@ public class BuildAccessToken extends AbstractOIDCResponseAction {
ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
return false;
}
+ assert accessTokenCtx != null;
accessTokenCtx.setLifetime(lifetime);
manipulationStrategy = tokenClaimsSetManipulationStrategyLookupStrategy.apply(profileRequestContext);
@@ -444,7 +455,8 @@ public class BuildAccessToken extends AbstractOIDCResponseAction {
final Scope scope = responseCtx.getScope() != null ? responseCtx.getScope() : new Scope();
log.debug("{} Building access token with scope: {}", getLogPrefix(), scope);
-
+
+ assert scope != null;
final boolean oidc = scope.contains("openid");
if (oidc) {
@@ -453,42 +465,42 @@ public class BuildAccessToken extends AbstractOIDCResponseAction {
log.debug("{} Building access token with audience: {}", getLogPrefix(), responseCtx.getAudience());
final Instant now = Instant.now();
+ assert accessTokenCtx != null;
final Instant dateExp = now.plus(accessTokenCtx.getLifetime());
+ assert dateExp != null;
final AccessTokenClaimsSet.Builder builder;
-
+
if (tokenClaimsSet != null) {
+ final TokenClaimsSet nonNullClaimsSet = tokenClaimsSet;
// We may not use original claims as input for scope / delivery claims as they may have been reduced.
builder = new AccessTokenClaimsSet.Builder(
- tokenClaimsSet,
+ nonNullClaimsSet,
scope,
oidc ? claims : null,
oidc ? claimsUI : null,
- Instant.now(),
+ now,
dateExp);
// Add additional bits.
builder.setAudience(responseCtx.getAudience());
+ assert idGenerator != null;
builder.setJWTID(idGenerator, xmlSafeIdentifier);
builder.setSessionIdentifier(responseCtx.getSessionId());
// Set root token identifier to contain jit from the claims set used for building the new token
- if (StringSupport.trimOrNull(tokenClaimsSet.getRootTokenIdentifier()) == null) {
- builder.setRootTokenIdentifier(tokenClaimsSet.getID());
+ if (StringSupport.trimOrNull(nonNullClaimsSet.getRootTokenIdentifier()) == null) {
+ builder.setRootTokenIdentifier(nonNullClaimsSet.getID());
}
} else {
final OIDCAuthenticationResponseConsentContext consentCtx =
consentContextLookupStrategy.apply(profileRequestContext);
final JSONArray consented = consentCtx != null ? consentCtx.getConsentedAttributes() : null;
-
+
builder = (Builder) new AccessTokenClaimsSet.Builder()
- .setJWTID(idGenerator, xmlSafeIdentifier)
.setClientID(clientID)
.setIssuer(issuer)
- .setPrincipal(subjectCtx.getPrincipalName())
- .setSubject(responseCtx.getSubject())
.setIssuedAt(now)
.setExpiresAt(dateExp)
.setACR(responseCtx.getAcr())
- .setAuthenticationTime(responseCtx.getAuthTime())
.setScope(scope)
.setAudience(responseCtx.getAudience())
.setDlClaims(claims)
@@ -497,31 +509,61 @@ public class BuildAccessToken extends AbstractOIDCResponseAction {
.setConsentEnabled(consentEnabledPredicate.test(profileRequestContext))
.setSessionIdentifier(responseCtx.getSessionId());
+ assert subjectCtx != null;
+ final String principal = subjectCtx.getPrincipalName();
+ if (principal != null) {
+ builder.setPrincipal(principal);
+ }
+
+ assert responseCtx != null;
+ final String subject = responseCtx.getSubject();
+ if (subject != null) {
+ builder.setSubject(subject);
+ }
+
+ assert responseCtx != null;
+ final Instant authTime = responseCtx.getAuthTime();
+ if (authTime != null) {
+ builder.setAuthenticationTime(authTime);
+ }
+
+ assert idGenerator != null;
+ builder.setJWTID(idGenerator, xmlSafeIdentifier);
+
if (authenticationRequest != null) {
- builder
- .setNonce(authenticationRequest.getNonce())
- .setClaimsRequest(authenticationRequest.getOIDCClaims());
+ final AuthenticationRequest nonNullAuthnRequest = authenticationRequest;
+ builder.setNonce(nonNullAuthnRequest.getNonce());
+ builder.setClaimsRequest(nonNullAuthnRequest.getOIDCClaims());
}
}
-
- if (jwtTokenType && responseCtx.getAccessTokenClaimSet() != null) {
- builder.setCustomClaims(responseCtx.getAccessTokenClaimSet().toJSONObject());
+
+ final ClaimsSet responseCtxClaimsSet = responseCtx.getAccessTokenClaimSet();
+ if (jwtTokenType && responseCtxClaimsSet != null) {
+ final JSONObject json = responseCtxClaimsSet.toJSONObject();
+ if (json != null) {
+ builder.setCustomClaims(json);
+ }
}
final AccessTokenClaimsSet claimsSet = builder.build();
if (manipulationStrategy != null) {
+ final JWTClaimsSet acClaimsSet = claimsSet.getClaimsSet();
+ assert acClaimsSet != null;
log.debug("{} Manipulation strategy has been set, applying it to the claims set {}", getLogPrefix(),
claimsSet.serialize());
+ assert manipulationStrategy != null;
final Map<String, Object> result = manipulationStrategy.apply(profileRequestContext,
- claimsSet.getClaimsSet().toJSONObject());
+ acClaimsSet.toJSONObject());
if (result == null) {
log.debug("{} Manipulation strategy returned null, leaving token claims set untouched.",
getLogPrefix());
} else {
log.debug("{} Applying the manipulated claims into the token claims set", getLogPrefix());
try {
- claimsSet.setClaimsSet(JWTClaimsSet.parse(result));
+ final JWTClaimsSet parsedSet = JWTClaimsSet.parse(result);
+ assert parsedSet != null;
+ claimsSet.setClaimsSet(parsedSet);
} catch (final ParseException e) {
log.error("{} The resulted claims set could not be transformed into ", getLogPrefix(), e);
ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
@@ -534,10 +576,16 @@ public class BuildAccessToken extends AbstractOIDCResponseAction {
try {
if (jwtTokenType) {
- accessTokenCtx.setJWT(new PlainJWT(sealClaims(claimsSet.getClaimsSet())));
+ final JWTClaimsSet acClaimsSet = claimsSet.getClaimsSet();
+ assert acClaimsSet != null;
+ assert accessTokenCtx != null;
+ accessTokenCtx.setJWT(new PlainJWT(sealClaims(acClaimsSet)));
log.debug("{} Claims stored to JWT access token: {}", getLogPrefix(), claimsSet.serialize());
} else {
- accessTokenCtx.setOpaque(claimsSet.serialize(dataSealer));
+ assert dataSealer != null;
+ final String sealedToken = claimsSet.serialize(dataSealer);
+ assert accessTokenCtx != null;
+ accessTokenCtx.setOpaque(sealedToken);
log.debug("{} Claims converted to opaque access token: {}", getLogPrefix(), claimsSet.serialize());
}
} catch (final DataSealerException | ParseException e) {
@@ -605,11 +653,17 @@ public class BuildAccessToken extends AbstractOIDCResponseAction {
}
// Wrap the sealed claims and re-embed back in original claims set.
- final String sealed = dataSealer.wrap(JWTClaimsSet.parse(toSeal).toString());
+ final JWTClaimsSet claimsSetToSeal = JWTClaimsSet.parse(toSeal);
+ assert claimsSetToSeal != null;
+ final String stringToSeal = claimsSetToSeal.toString();
+ assert stringToSeal != null;
+ final String sealed = dataSealer.wrap(stringToSeal);
map.put(TokenClaimsSet.KEY_SEALED_FOR_OP, sealed);
// Re-parse the claims.
- return JWTClaimsSet.parse(map);
+ final JWTClaimsSet result = JWTClaimsSet.parse(map);
+ assert result != null;
+ return result;
}
}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/BuildRevokeTokenErrorResponseFromEvent.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/BuildRevokeTokenErrorResponseFromEvent.java
index 09e3cf14..7f747795 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/BuildRevokeTokenErrorResponseFromEvent.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/BuildRevokeTokenErrorResponseFromEvent.java
@@ -14,6 +14,8 @@
package net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl;
+import javax.annotation.Nonnull;
+
import org.opensaml.profile.context.EventContext;
import org.opensaml.profile.context.ProfileRequestContext;
@@ -30,7 +32,7 @@ public class BuildRevokeTokenErrorResponseFromEvent
extends AbstractBuildErrorResponseFromEvent<OAuth2RevocationErrorResponse> {
@Override
- protected OAuth2RevocationErrorResponse buildErrorResponse(final ErrorObject error,
+ protected OAuth2RevocationErrorResponse buildErrorResponse(@Nonnull final ErrorObject error,
final ProfileRequestContext profileRequestContext) {
return new OAuth2RevocationErrorResponse(error);
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundIntrospectionResponseMessage.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundIntrospectionResponseMessage.java
index 45ffba40..9aff26de 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundIntrospectionResponseMessage.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundIntrospectionResponseMessage.java
@@ -21,7 +21,6 @@ import javax.annotation.Nonnull;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.oauth2.sdk.Scope;
@@ -35,6 +34,7 @@ import com.nimbusds.oauth2.sdk.token.AccessTokenType;
import net.shibboleth.idp.plugin.oidc.op.oauth2.messaging.context.OAuth2TokenMgmtResponseContext;
import net.shibboleth.idp.plugin.oidc.op.token.support.TokenClaimsSet;
import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Action that forms outbound token introspection success message. Formed message is set to
@@ -49,17 +49,18 @@ public class FormOutboundIntrospectionResponseMessage extends AbstractProfileAct
@Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
final OAuth2TokenMgmtResponseContext ctx =
- profileRequestContext.getOutboundMessageContext().getSubcontext(
+ profileRequestContext.ensureOutboundMessageContext().getSubcontext(
OAuth2TokenMgmtResponseContext.class);
if (ctx == null || ctx.getTokenClaimsSet() == null) {
log.debug("{} Introspection of token failed, token was not valid", getLogPrefix());
- profileRequestContext.getOutboundMessageContext().setMessage(
+ profileRequestContext.ensureOutboundMessageContext().setMessage(
new TokenIntrospectionSuccessResponse.Builder(false).build());
return;
}
final JWTClaimsSet tokenClaimsSet = ctx.getTokenClaimsSet();
+ assert tokenClaimsSet != null;
try {
String clientID = tokenClaimsSet.getStringClaim(TokenClaimsSet.KEY_CLIENTID);
@@ -94,11 +95,11 @@ public class FormOutboundIntrospectionResponseMessage extends AbstractProfileAct
}
- profileRequestContext.getOutboundMessageContext().setMessage(builder.build());
+ profileRequestContext.ensureOutboundMessageContext().setMessage(builder.build());
} catch (final ParseException e) {
log.error("{} Failure extracting claims for response", getLogPrefix(), e);
- profileRequestContext.getOutboundMessageContext().setMessage(
+ profileRequestContext.ensureOutboundMessageContext().setMessage(
new TokenIntrospectionSuccessResponse.Builder(false).build());
}
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundRevokeTokenResponseMessage.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundRevokeTokenResponseMessage.java
index f35f317d..152b2d6e 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundRevokeTokenResponseMessage.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundRevokeTokenResponseMessage.java
@@ -30,7 +30,7 @@ public class FormOutboundRevokeTokenResponseMessage extends AbstractProfileActio
/** {@inheritDoc} */
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
- profileRequestContext.getOutboundMessageContext().setMessage(new OAuth2RevocationSuccessResponse());
+ profileRequestContext.ensureOutboundMessageContext().setMessage(new OAuth2RevocationSuccessResponse());
}
}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/RevokeToken.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/RevokeToken.java
index e6d7f1bf..2d4086a6 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/RevokeToken.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/RevokeToken.java
@@ -25,7 +25,6 @@ import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.storage.RevocationCache;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.jwt.JWTClaimsSet;
@@ -42,6 +41,7 @@ import net.shibboleth.oidc.profile.oauth2.config.OAuth2TokenRevocationConfigurat
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.primitive.StringSupport;
/**
@@ -169,8 +169,8 @@ public class RevokeToken extends AbstractProfileAction {
return false;
}
- final OAuth2TokenMgmtResponseContext ctx = profileRequestContext.getOutboundMessageContext().getSubcontext(
- OAuth2TokenMgmtResponseContext.class);
+ final OAuth2TokenMgmtResponseContext ctx = profileRequestContext.ensureOutboundMessageContext()
+ .getSubcontext(OAuth2TokenMgmtResponseContext.class);
if (ctx == null || ctx.getTokenClaimsSet() == null) {
log.debug("{} No token validated for revocation, assumed to be invalid", getLogPrefix());
return false;
@@ -209,6 +209,8 @@ public class RevokeToken extends AbstractProfileAction {
} else {
idToRevoke = rootJti;
}
+ assert idToRevoke != null;
+ assert revocationLifetime != null;
if (revocationCache.revoke(RevocationCacheContexts.AUTHORIZATION_CODE, idToRevoke, revocationLifetime)) {
log.debug("{} Revoked all tokens based on ID '{}'", getLogPrefix(), idToRevoke);
} else {
@@ -216,6 +218,7 @@ public class RevokeToken extends AbstractProfileAction {
ActionSupport.buildEvent(profileRequestContext, OidcEventIds.REVOCATION_FAILED);
}
} else if (OAuth2TokenRevocationMethod.TOKEN.equals(revocationMethod)) {
+ assert revocationLifetime != null;
if (revocationCache.revoke(RevocationCacheContexts.SINGLE_ACCESS_OR_REFRESH_TOKENS, jti,
revocationLifetime)) {
log.debug("{} Revoked the single token with ID '{}'", getLogPrefix(), jti);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetAccessTokenToResponseContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetAccessTokenToResponseContext.java
index 3cf5f664..43961b52 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetAccessTokenToResponseContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetAccessTokenToResponseContext.java
@@ -14,6 +14,7 @@
package net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl;
+import java.time.Duration;
import java.util.function.Function;
import javax.annotation.Nonnull;
@@ -23,12 +24,14 @@ import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import com.nimbusds.jwt.JWT;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.AccessTokenContext;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
import net.shibboleth.idp.plugin.oidc.op.profile.impl.AbstractOIDCResponseAction;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.opensaml.profile.action.ActionSupport;
@@ -52,9 +55,12 @@ public class SetAccessTokenToResponseContext extends AbstractOIDCResponseAction
/** Constructor. */
public SetAccessTokenToResponseContext() {
// PRC -> outbound message context -> OIDC response context -> ATC
- accessTokenContextLookupStrategy = new ChildContextLookup<>(AccessTokenContext.class).compose(
- new ChildContextLookup<>(OIDCAuthenticationResponseContext.class).compose(
- new OutboundMessageContextLookup()));
+ final Function<ProfileRequestContext,AccessTokenContext> atcls =
+ new ChildContextLookup<>(AccessTokenContext.class).compose(
+ new ChildContextLookup<>(OIDCAuthenticationResponseContext.class).compose(
+ new OutboundMessageContextLookup()));
+ assert atcls != null;
+ accessTokenContextLookupStrategy = atcls;
}
/**
@@ -84,12 +90,19 @@ public class SetAccessTokenToResponseContext extends AbstractOIDCResponseAction
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
return false;
}
-
- if (tokenCtx.getJWT() == null && tokenCtx.getOpaque() == null) {
+
+ final AccessTokenContext nonNullTokenCtx = tokenCtx;
+ assert nonNullTokenCtx != null;
+ if (nonNullTokenCtx.getJWT() == null && nonNullTokenCtx.getOpaque() == null) {
log.debug("{} Access token is missing", getLogPrefix());
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
return false;
}
+ if (nonNullTokenCtx.getLifetime() == null) {
+ log.debug("{} Access token lifetime is missing", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
return true;
}
@@ -97,15 +110,21 @@ public class SetAccessTokenToResponseContext extends AbstractOIDCResponseAction
/** {@inheritDoc} */
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-
+
+ final AccessTokenContext nonNullTokenCtx = tokenCtx;
+ assert nonNullTokenCtx != null;
+
final String token;
- if (tokenCtx.getJWT() != null) {
- token = tokenCtx.getJWT().serialize();
+ final JWT jwt = nonNullTokenCtx.getJWT();
+ if (jwt != null) {
+ token = jwt.serialize();
} else {
- token = tokenCtx.getOpaque();
+ token = nonNullTokenCtx.getOpaque();
}
-
- getOidcResponseContext().setAccessToken(token, tokenCtx.getLifetime(), getOidcResponseContext().getScope());
+
+ final Duration lifetime = nonNullTokenCtx.getLifetime();
+ assert lifetime != null;
+ getOidcResponseContext().setAccessToken(token, lifetime, getOidcResponseContext().getScope());
}
}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetAuthorizationCodeToResponseContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetAuthorizationCodeToResponseContext.java
index 8559122d..5262bec6 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetAuthorizationCodeToResponseContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetAuthorizationCodeToResponseContext.java
@@ -14,6 +14,7 @@
package net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl;
+import java.net.URI;
import java.text.ParseException;
import java.time.Duration;
import java.time.Instant;
@@ -27,10 +28,11 @@ import javax.annotation.Nullable;
import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.jwt.JWTClaimsSet;
+import com.nimbusds.oauth2.sdk.AuthorizationRequest;
import com.nimbusds.oauth2.sdk.Scope;
+import com.nimbusds.oauth2.sdk.id.ClientID;
import com.nimbusds.openid.connect.sdk.claims.ClaimsSet;
import net.minidev.json.JSONArray;
import net.shibboleth.idp.authn.context.SubjectContext;
@@ -51,6 +53,7 @@ import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.logic.FunctionSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.security.DataSealer;
import net.shibboleth.shared.security.DataSealerException;
import net.shibboleth.shared.security.IdentifierGenerationStrategy;
@@ -129,12 +132,19 @@ public class SetAuthorizationCodeToResponseContext extends AbstractOAuthAuthoriz
public SetAuthorizationCodeToResponseContext() {
codeChallengeLookupStrategy = new DefaultRequestCodeChallengeLookupFunction();
codeChallengeMethodLookupStrategy = new DefaultRequestCodeChallengeMethodLookupFunction();
- tokenClaimsContextLookupStrategy =
+
+ final Function<ProfileRequestContext, OIDCAuthenticationResponseTokenClaimsContext> tccls =
new ChildContextLookup<>(OIDCAuthenticationResponseTokenClaimsContext.class).compose(
new OIDCAuthenticationResponseContextLookupFunction());
- consentContextLookupStrategy =
+ assert tccls != null;
+ tokenClaimsContextLookupStrategy = tccls;
+
+ final Function<ProfileRequestContext, OIDCAuthenticationResponseConsentContext> ccls =
new ChildContextLookup<>(OIDCAuthenticationResponseConsentContext.class).compose(
new OIDCAuthenticationResponseContextLookupFunction());
+ assert ccls != null;
+ consentContextLookupStrategy = ccls;
+
authzCodeLifetimeLookupStrategy = new AuthzCodeLifetimeLookupFunction();
issuerLookupStrategy = new IssuerLookupFunction();
consentEnabledPredicate = new AttributeConsentFlowEnabledPredicate();
@@ -334,6 +344,9 @@ public class SetAuthorizationCodeToResponseContext extends AbstractOAuthAuthoriz
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
final OIDCAuthenticationResponseContext responseCtx = getOidcResponseContext();
+ assert responseCtx != null;
+ final AuthorizationRequest authorizationRequest = getAuthorizationRequest();
+ assert authorizationRequest != null;
final OIDCAuthenticationResponseConsentContext consentCtx =
consentContextLookupStrategy.apply(profileRequestContext);
@@ -348,18 +361,36 @@ public class SetAuthorizationCodeToResponseContext extends AbstractOAuthAuthoriz
claimsID = tokenClaimsCtx.getIdtokenClaims();
claimsUI = tokenClaimsCtx.getUserinfoClaims();
}
- final Instant dateExp = Instant.now().plus(authzCodeLifetime);
+ final Instant now = Instant.now();
+ final Instant dateExp = now.plus(authzCodeLifetime);
+ assert dateExp != null;
final Scope scope = responseCtx.getScope();
+ final ClientID clientId = authorizationRequest.getClientID();
+ assert clientId != null;
+ final String issuer = issuerLookupStrategy.apply(profileRequestContext);
+ assert subjectCtx != null;
+ final String principal = subjectCtx.getPrincipalName();
+ final String subject = responseCtx.getSubject();
+ final Instant authTime = responseCtx.getAuthTime();
+ final URI redirectUri = responseCtx.getRedirectURI();
+ if (issuer == null || principal == null | subject == null || authTime == null || redirectUri == null) {
+ log.warn("{} Mandatory claims set variable is missing", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return;
+ }
+ assert principal != null;
+ assert subject != null;
+ assert idGenerator != null;
final AuthorizeCodeClaimsSet claimsSet = new AuthorizeCodeClaimsSet.Builder()
.setJWTID(idGenerator, xmlSafeIdentifier)
- .setClientID(getAuthorizationRequest().getClientID())
- .setIssuer(issuerLookupStrategy.apply(profileRequestContext))
- .setPrincipal(subjectCtx.getPrincipalName())
- .setSubject(responseCtx.getSubject())
- .setIssuedAt(Instant.now())
+ .setClientID(clientId)
+ .setIssuer(issuer)
+ .setPrincipal(principal)
+ .setSubject(subject)
+ .setIssuedAt(now)
.setExpiresAt(dateExp)
- .setAuthenticationTime(responseCtx.getAuthTime())
- .setRedirectURI(responseCtx.getRedirectURI())
+ .setAuthenticationTime(authTime)
+ .setRedirectURI(redirectUri)
.setScope(scope != null ? scope : new Scope())
.setAudience(responseCtx.getAudience())
.setACR(responseCtx.getAcr())
@@ -375,17 +406,22 @@ public class SetAuthorizationCodeToResponseContext extends AbstractOAuthAuthoriz
.build();
if (manipulationStrategy != null) {
+ final JWTClaimsSet jwtClaimsSet = claimsSet.getClaimsSet();
+ assert jwtClaimsSet != null;
log.debug("{} Manipulation strategy has been set, applying it to the claims set {}", getLogPrefix(),
claimsSet.serialize());
+ assert manipulationStrategy != null;
final Map<String, Object> result = manipulationStrategy.apply(profileRequestContext,
- claimsSet.getClaimsSet().toJSONObject());
+ jwtClaimsSet.toJSONObject());
if (result == null) {
log.debug("{} Manipulation strategy returned null, leaving token claims set untouched.",
getLogPrefix());
} else {
log.debug("{} Applying the manipulated claims into the token claims set", getLogPrefix());
try {
- claimsSet.setClaimsSet(JWTClaimsSet.parse(result));
+ final JWTClaimsSet parsedClaimsSet = JWTClaimsSet.parse(result);
+ assert parsedClaimsSet != null;
+ claimsSet.setClaimsSet(parsedClaimsSet);
} catch (final ParseException e) {
log.error("{} The resulted claims set could not be transformed into ", getLogPrefix(), e);
ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
@@ -399,7 +435,9 @@ public class SetAuthorizationCodeToResponseContext extends AbstractOAuthAuthoriz
// We set token claims set to response context for possible access token generation.
responseCtx.setAuthorizationGrantClaimsSet(claimsSet);
try {
- responseCtx.setAuthorizationCode(claimsSet.serialize(dataSealer));
+ assert dataSealer != null;
+ final String sealedCode = claimsSet.serialize(dataSealer);
+ responseCtx.setAuthorizationCode(sealedCode);
log.debug("{} Setting authz code {} as {} to response context ", getLogPrefix(), claimsSet.serialize(),
responseCtx.getAuthorizationCode());
} catch (final DataSealerException e) {
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetRequestObjectToResponseContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetRequestObjectToResponseContext.java
index 17a2a457..61952caf 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetRequestObjectToResponseContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/SetRequestObjectToResponseContext.java
@@ -36,15 +36,19 @@ import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.security.httpclient.HttpClientSecurityParameters;
import org.opensaml.security.httpclient.HttpClientSecuritySupport;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTParser;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
+import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
import net.shibboleth.oidc.profile.core.OidcEventIds;
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Action that stored request object to {@link OIDCAuthenticationResponseContext}. The request
@@ -103,6 +107,7 @@ public class SetRequestObjectToResponseContext extends AbstractOAuthAuthorizatio
@Nonnull
private HttpClientContext buildHttpContext(@Nonnull final ClassicHttpRequest request) {
final HttpClientContext clientContext = HttpClientContext.create();
+ assert clientContext != null;
HttpClientSecuritySupport.marshalSecurityParameters(clientContext, httpClientSecurityParameters, false);
HttpClientSecuritySupport.addDefaultTLSTrustEngineCriteria(clientContext, request);
return clientContext;
@@ -122,11 +127,11 @@ public class SetRequestObjectToResponseContext extends AbstractOAuthAuthorizatio
if (!super.doPreExecute(profileRequestContext)) {
return false;
}
-
+
if (!getAuthorizationRequest().specifiesRequestObject()) {
if (requestObjectEnforcedPredicate.test(profileRequestContext)) {
log.warn("{} No request_uri or request by value, even though it's enforced for {}", getLogPrefix(),
- getMetadataContext().getClientInformation().getID().getValue());
+ getAuthorizationRequest().getClientID().getValue());
ActionSupport.buildEvent(profileRequestContext, OidcEventIds.MISSING_MANDATORY_REQUEST_OBJECT);
} else {
log.debug("{} No request_uri or request by value, nothing to do", getLogPrefix());
@@ -147,21 +152,28 @@ public class SetRequestObjectToResponseContext extends AbstractOAuthAuthorizatio
/** {@inheritDoc} */
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
- if (getAuthorizationRequest().getRequestObject() != null) {
- getOidcResponseContext().setRequestObject(getAuthorizationRequest().getRequestObject());
+ final OIDCAuthenticationResponseContext oidcResponseContext = getOidcResponseContext();
+ assert oidcResponseContext != null;
+ final JWT requestObject = getAuthorizationRequest().getRequestObject();
+ if (requestObject != null) {
+ oidcResponseContext.setRequestObject(requestObject);
log.debug("{} Request object {} by value stored to oidc response context", getLogPrefix(),
- getOidcResponseContext().getRequestObject().serialize());
+ requestObject.serialize());
return;
}
// Request URI must be found in metadata.
boolean authorized = false;
- if (getMetadataContext() != null && getMetadataContext().getClientInformation() != null) {
- final OIDCClientMetadata metadata = getMetadataContext().getClientInformation().getOIDCMetadata();
- if (metadata != null) {
- final Set<URI> allowedURIs = metadata.getRequestObjectURIs();
- if (allowedURIs != null) {
- authorized = allowedURIs.contains(getAuthorizationRequest().getRequestURI());
+ final OIDCMetadataContext metadataContext = getMetadataContext();
+ if (metadataContext != null) {
+ final OIDCClientInformation clientInformation = metadataContext.getClientInformation();
+ if (clientInformation != null) {
+ final OIDCClientMetadata metadata = clientInformation.getOIDCMetadata();
+ if (metadata != null) {
+ final Set<URI> allowedURIs = metadata.getRequestObjectURIs();
+ if (allowedURIs != null) {
+ authorized = allowedURIs.contains(getAuthorizationRequest().getRequestURI());
+ }
}
}
}
@@ -176,13 +188,15 @@ public class SetRequestObjectToResponseContext extends AbstractOAuthAuthorizatio
final HttpGet httpRequest = new HttpGet(getAuthorizationRequest().getRequestURI());
final HttpClientContext httpContext = buildHttpContext(httpRequest);
try (final ClassicHttpResponse response = httpClient.executeOpen(null, httpRequest, httpContext)) {
- HttpClientSecuritySupport.checkTLSCredentialEvaluated(httpContext, httpRequest.getUri().getScheme());
+ final String scheme = httpRequest.getUri().getScheme();
+ assert scheme != null;
+ HttpClientSecuritySupport.checkTLSCredentialEvaluated(httpContext, scheme);
if (response.getCode() == HttpStatus.SC_OK) {
- final String requestObject = EntityUtils.toString(response.getEntity());
+ final String requestObjectValue = EntityUtils.toString(response.getEntity());
try {
- getOidcResponseContext().setRequestObject(JWTParser.parse(requestObject));
+ oidcResponseContext.setRequestObject(JWTParser.parse(requestObjectValue));
log.debug("{} Request object {} by reference stored to oidc response context", getLogPrefix(),
- getOidcResponseContext().getRequestObject().serialize());
+ JWTParser.parse(requestObjectValue).serialize());
return;
} catch (final ParseException e) {
log.error("{} Unable to parse request object from request_uri, {}", getLogPrefix(), e.getMessage());
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAudience.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAudience.java
index d672b5b5..b2854d38 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAudience.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAudience.java
@@ -30,18 +30,18 @@ import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.profile.context.ProxiedRequesterContext;
import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
-import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseTokenClaimsContext;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.ClientInfoAudienceLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultOIDCMetadataContextLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.TokenRequestAudienceLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.impl.AbstractOIDCAuthenticationResponseAction;
import net.shibboleth.idp.plugin.oidc.op.profile.logic.IssueIDTokenCondition;
+import net.shibboleth.idp.plugin.oidc.op.token.support.TokenClaimsSet;
import net.shibboleth.oidc.profile.core.OidcEventIds;
import net.shibboleth.profile.context.navigate.IssuerLookupFunction;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Action that validates requested resource/audience values against a computed set of "allowed"
@@ -79,19 +79,20 @@ public class ValidateAudience extends AbstractOIDCAuthenticationResponseAction {
/** Whether the request includes the OP as an audience. */
@Nonnull private Predicate<ProfileRequestContext> selfAudienceCondition;
- /** Strategy used to locate the {@link OIDCAuthenticationResponseTokenClaimsContext}. */
- @Nonnull
- private Function<ProfileRequestContext,OIDCAuthenticationResponseTokenClaimsContext>
- tokenClaimsContextLookupStrategy;
-
/** Constructor. */
public ValidateAudience() {
requestedAudienceLookupStrategy = new TokenRequestAudienceLookupFunction();
relyingPartyIdLookupStrategy = new IssuerLookupFunction();
- allowedAudienceLookupStrategy = new ClientInfoAudienceLookupFunction().compose(
+ final Function<ProfileRequestContext,List<String>> aals = new ClientInfoAudienceLookupFunction().compose(
new DefaultOIDCMetadataContextLookupFunction());
- proxiedRequesterContextCreationStrategy = new ChildContextLookup<>(ProxiedRequesterContext.class, true).compose(
- new OutboundMessageContextLookup());
+ assert aals != null;
+ allowedAudienceLookupStrategy = aals;
+ final Function<ProfileRequestContext,ProxiedRequesterContext> prccs =
+ new ChildContextLookup<>(ProxiedRequesterContext.class, true).compose(
+ new OutboundMessageContextLookup());
+ assert prccs != null;
+ proxiedRequesterContextCreationStrategy = prccs;
+
// openid scope -> we're issuing an ID token -> the OP will be an audience for the access token
selfAudienceCondition = new IssueIDTokenCondition();
}
@@ -172,8 +173,10 @@ public class ValidateAudience extends AbstractOIDCAuthenticationResponseAction {
// These come from a previous authorization grant (authz code or refresh token).
List<String> previouslyGrantedAudience = null;
- if (getOidcResponseContext().getAuthorizationGrantClaimsSet() != null) {
- previouslyGrantedAudience = getOidcResponseContext().getAuthorizationGrantClaimsSet().getAudience();
+ final OIDCAuthenticationResponseContext oidcResponseContext = getOidcResponseContext();
+ final TokenClaimsSet grantClaimsSet = oidcResponseContext.getAuthorizationGrantClaimsSet();
+ if (grantClaimsSet != null) {
+ previouslyGrantedAudience = grantClaimsSet.getAudience();
}
// These come from a request object or parameter. Absent by definition on the UserInfo endpoint.
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAuthorizationRequestType.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAuthorizationRequestType.java
index f2226bde..71aa3df8 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAuthorizationRequestType.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateAuthorizationRequestType.java
@@ -22,12 +22,12 @@ import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.oauth2.sdk.AuthorizationRequest;
import net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultAuthorizationRequestTypeValidationStrategy;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* An action that validates the incoming OAuth2 authorization request via configurable strategy.
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateClientIDAgainstPolicy.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateClientIDAgainstPolicy.java
index 25ee34e3..fbf6f0fa 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateClientIDAgainstPolicy.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateClientIDAgainstPolicy.java
@@ -26,7 +26,6 @@ import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.oauth2.sdk.id.ClientID;
@@ -40,6 +39,7 @@ import net.shibboleth.oidc.profile.config.navigate.UnregisteredClientPolicyLooku
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.collection.Pair;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Validates a client ID against unregistered client policy via configurable policy enforcer. The validation is done
@@ -119,7 +119,7 @@ public class ValidateClientIDAgainstPolicy extends AbstractProfileAction {
}
final OIDCMetadataContext oidcMetadataContext =
- profileRequestContext.getInboundMessageContext().getSubcontext(OIDCMetadataContext.class);
+ profileRequestContext.ensureInboundMessageContext().getSubcontext(OIDCMetadataContext.class);
if (oidcMetadataContext != null && oidcMetadataContext.getClientInformation() != null) {
log.debug("{} OIDC metadata context is populated: client ID has already been validated against metadata",
getLogPrefix());
@@ -145,14 +145,20 @@ public class ValidateClientIDAgainstPolicy extends AbstractProfileAction {
/** {@inheritDoc} */
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-
+ assert clientId != null;
+ final String clientIdValue = clientId.getValue();
+ assert clientIdValue != null;
+ assert policies != null;
final Pair<Object, Boolean> enforcerResult =
- unregisteredClientPolicyEnforcer.apply(clientId.getValue(), policies.get("client_id"));
- if (enforcerResult.getSecond() && clientId.getValue().equals(enforcerResult.getFirst())) {
- log.debug("{} The client ID {} is compliant with the policy", getLogPrefix(), clientId.getValue());
- return;
+ unregisteredClientPolicyEnforcer.apply(clientIdValue, policies.get("client_id"));
+ if (enforcerResult != null) {
+ final Boolean result = enforcerResult.getSecond();
+ if (result != null && result.booleanValue() && clientIdValue.equals(enforcerResult.getFirst())) {
+ log.debug("{} The client ID {} is compliant with the policy", getLogPrefix(), clientIdValue);
+ return;
+ }
}
- log.warn("{} The client ID {} is not compliant with the policy", getLogPrefix(), clientId);
+ log.warn("{} The client ID {} is not compliant with the policy", getLogPrefix(), clientIdValue);
ActionSupport.buildEvent(profileRequestContext, EventIds.ACCESS_DENIED);
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateCodeChallenge.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateCodeChallenge.java
index 2242c5ea..c7582a47 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateCodeChallenge.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateCodeChallenge.java
@@ -23,7 +23,6 @@ import javax.annotation.Nullable;
import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequestCodeChallengeLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequestCodeChallengeMethodLookupFunction;
@@ -31,6 +30,8 @@ import net.shibboleth.oidc.profile.config.logic.AllowPKCEPlainPredicate;
import net.shibboleth.oidc.profile.config.logic.ForcePKCEPredicate;
import net.shibboleth.oidc.profile.core.OidcEventIds;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
/**
* Validates the presence of PKCE code challenge parameter from the incoming authentication request.
@@ -130,7 +131,7 @@ public class ValidateCodeChallenge extends AbstractOAuthAuthorizationResponseAc
codeChallenge = codeChallengeLookupStrategy.apply(profileRequestContext);
- if ((codeChallenge == null || codeChallenge.isEmpty()) && !forcePKCE) {
+ if (StringSupport.trimOrNull(codeChallenge) == null && !forcePKCE) {
log.debug("{} No PKCE code challenge in request, nothing to do", getLogPrefix());
return false;
}
@@ -142,13 +143,13 @@ public class ValidateCodeChallenge extends AbstractOAuthAuthorizationResponseAc
/** {@inheritDoc} */
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
- if (codeChallenge == null || codeChallenge.isEmpty()) {
+ if (StringSupport.trimOrNull(codeChallenge) == null) {
log.warn("{} No PKCE code challenge presented in authentication request" +
" even though required by the profile configuration", getLogPrefix());
ActionSupport.buildEvent(profileRequestContext, OidcEventIds.MISSING_PKCE_CODE_CHALLENGE);
return;
}
- if (codeChallengeMethod == null || codeChallengeMethod.isEmpty() || "plain".equals(codeChallengeMethod)) {
+ if (StringSupport.trimOrNull(codeChallengeMethod) == null || "plain".equals(codeChallengeMethod)) {
if (!plainPKCE) {
log.warn("{} Plain PKCE code challenge method not allowed", getLogPrefix());
ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_PKCE_TRANSFORMATION_METHOD);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURI.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURI.java
index 69b47553..929eff93 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURI.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRedirectURI.java
@@ -25,8 +25,8 @@ import javax.annotation.Nonnull;
import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequestRedirectURILookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultValidRedirectUrisLookupFunction;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
@@ -39,6 +39,7 @@ import net.shibboleth.shared.collection.Pair;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Action that validates redirect uri is expected. Validated redirect uri is stored to response context.
@@ -159,7 +160,10 @@ public class ValidateRedirectURI extends AbstractOAuthAuthorizationResponseActio
@Override
protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
final URI requestRedirectURI = redirectURILookupStrategy.apply(profileRequestContext);
-
+
+ final OIDCAuthenticationResponseContext oidcResponseContext = getOidcResponseContext();
+ assert oidcResponseContext != null;
+
if (requestRedirectURI != null && getMetadataContext() == null) {
final Map<String, UnregisteredClientPolicy> policies =
unregisteredClientPolicyLookupStrategy.apply(profileRequestContext);
@@ -167,11 +171,15 @@ public class ValidateRedirectURI extends AbstractOAuthAuthorizationResponseActio
final Pair<Object, Boolean> result =
unregisteredClientPolicyEnforcer.apply(requestRedirectURI.toString(),
policies.get("redirect_uri"));
- if (result.getSecond() && requestRedirectURI.toString().equals(result.getFirst())) {
- log.debug("{} Redirection URI {} accepted by the policy for unregistered clients", getLogPrefix(),
- requestRedirectURI);
- getOidcResponseContext().setRedirectURI(requestRedirectURI);
- return;
+ if (result != null) {
+ final Boolean enforcerResult = result.getSecond();
+ if (enforcerResult != null && enforcerResult.booleanValue()
+ && requestRedirectURI.toString().equals(result.getFirst())) {
+ log.debug("{} Redirection URI {} accepted by the policy for unregistered clients", getLogPrefix(),
+ requestRedirectURI);
+ oidcResponseContext.setRedirectURI(requestRedirectURI);
+ return;
+ }
}
}
log.warn("{} Redirection URI {} is not accepted by the policy for unregistered clients", getLogPrefix(),
@@ -194,7 +202,7 @@ public class ValidateRedirectURI extends AbstractOAuthAuthorizationResponseActio
}
if (redirectionURIs.contains(requestRedirectURI)) {
- getOidcResponseContext().setRedirectURI(requestRedirectURI);
+ oidcResponseContext.setRedirectURI(requestRedirectURI);
log.debug("{} Redirection URI validated {}", getLogPrefix(), requestRedirectURI);
return;
}
@@ -235,7 +243,9 @@ public class ValidateRedirectURI extends AbstractOAuthAuthorizationResponseActio
if (singleRegisteredUri.equals(singleValidUri)) {
log.debug("{} No requested redirect_uri found, but allowing it due to single trusted value {}",
getLogPrefix(), singleRegisteredUri);
- getOidcResponseContext().setRedirectURI(singleRegisteredUri);
+ final OIDCAuthenticationResponseContext oidcResponseContext = getOidcResponseContext();
+ assert oidcResponseContext != null;
+ oidcResponseContext.setRedirectURI(singleRegisteredUri);
return;
} else {
log.warn("{} Registered URI '{}' did not match with the valid one '{}'", getLogPrefix(),
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRequestObject.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRequestObject.java
index 30a442ba..cd6a4c49 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRequestObject.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateRequestObject.java
@@ -15,17 +15,13 @@
package net.shibboleth.idp.plugin.oidc.op.oauth2.profile.impl;
import java.text.ParseException;
-import java.util.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jwt.JWT;
@@ -34,14 +30,17 @@ import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.SignedJWT;
import com.nimbusds.oauth2.sdk.ResponseType;
import com.nimbusds.oauth2.sdk.id.ClientID;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
import net.shibboleth.oidc.jwt.claims.ClaimsValidator;
import net.shibboleth.oidc.jwt.claims.JWTValidationException;
+import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
import net.shibboleth.oidc.profile.core.OidcEventIds;
-import net.shibboleth.oidc.security.jose.context.SecurityParametersContext;
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Action validates request object in response context.
@@ -51,11 +50,6 @@ public class ValidateRequestObject extends AbstractOAuthAuthorizationResponseAct
/** Class logger. */
@Nonnull private Logger log = LoggerFactory.getLogger(ValidateRequestObject.class);
- /**
- * Strategy used to locate the {@link SecurityParametersContext} to use for signing.
- */
- @Nonnull private Function<ProfileRequestContext, SecurityParametersContext> securityParametersLookupStrategy;
-
/** Request Object. */
@Nullable private JWT requestObject;
@@ -67,21 +61,6 @@ public class ValidateRequestObject extends AbstractOAuthAuthorizationResponseAct
/** Constructor. */
public ValidateRequestObject() {
- securityParametersLookupStrategy = new ChildContextLookup<>(SecurityParametersContext.class).compose(
- new InboundMessageContextLookup());
- }
-
- /**
- * Set the strategy used to locate the {@link SecurityParametersContext} to use.
- *
- * @param strategy lookup strategy
- */
- public void setSecurityParametersLookupStrategy(
- @Nonnull final Function<ProfileRequestContext, SecurityParametersContext> strategy) {
- ifInitializedThrowUnmodifiabledComponentException();
-
- securityParametersLookupStrategy =
- Constraint.isNotNull(strategy, "SecurityParameterContext lookup strategy cannot be null");
}
/**
@@ -125,7 +104,9 @@ public class ValidateRequestObject extends AbstractOAuthAuthorizationResponseAct
return false;
}
- requestObject = getOidcResponseContext().getRequestObject();
+ final OIDCAuthenticationResponseContext oidcResponseContext = getOidcResponseContext();
+ assert oidcResponseContext != null;
+ requestObject = oidcResponseContext.getRequestObject();
if (requestObject == null) {
log.debug("{} No request object, nothing to do", getLogPrefix());
return false;
@@ -146,19 +127,26 @@ public class ValidateRequestObject extends AbstractOAuthAuthorizationResponseAct
ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_REQUEST_OBJECT);
return;
}
- final JWSAlgorithm requestObjectAlg =
- getMetadataContext().getClientInformation().getOIDCMetadata().getRequestObjectJWSAlg();
- if (requestObjectAlg != null && !"none".equals(requestObjectAlg.getName())) {
- log.error("{} Request object is not signed, registered alg is {}", getLogPrefix(),
- requestObjectAlg.getName());
- ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_REQUEST_OBJECT);
- return;
+ final OIDCMetadataContext metadataContext = getMetadataContext();
+ if (metadataContext != null) {
+ final OIDCClientInformation clientInformation = metadataContext.getClientInformation();
+ if (clientInformation != null && clientInformation.getOIDCMetadata() != null) {
+ final JWSAlgorithm requestObjectAlg =
+ clientInformation.getOIDCMetadata().getRequestObjectJWSAlg();
+ if (requestObjectAlg != null && !"none".equals(requestObjectAlg.getName())) {
+ log.error("{} Request object is not signed, registered alg is {}", getLogPrefix(),
+ requestObjectAlg.getName());
+ ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_REQUEST_OBJECT);
+ return;
+ }
+ }
}
}
final JWTClaimsSet claimsSet;
// Validate still client_id and response_type values
try {
+ assert requestObject != null;
claimsSet = requestObject.getJWTClaimsSet();
if (claimsSet.getClaims().containsKey("client_id")
&& !getAuthorizationRequest().getClientID()
@@ -169,7 +157,7 @@ public class ValidateRequestObject extends AbstractOAuthAuthorizationResponseAct
}
if (claimsSet.getClaims().containsKey("response_type")
&& !getAuthorizationRequest().getResponseType().equals(new ResponseType(
- ((String) requestObject.getJWTClaimsSet().getClaim("response_type")).split(" ")))) {
+ ((String) claimsSet.getClaim("response_type")).split(" ")))) {
log.error("{} response_type in request object not matching response_type request parameter",
getLogPrefix());
ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_REQUEST_OBJECT);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseType.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseType.java
index a44bbebe..b2f5aa10 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseType.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateResponseType.java
@@ -24,13 +24,14 @@ import javax.annotation.Nonnull;
import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.oauth2.sdk.ResponseType;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequestResponseTypeLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultValidResponseTypesLookupFunction;
+import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.UnregisteredClientPolicy;
import net.shibboleth.oidc.metadata.policy.impl.DefaultMetadataPolicyEnforcer;
@@ -38,6 +39,7 @@ import net.shibboleth.oidc.profile.config.navigate.UnregisteredClientPolicyLooku
import net.shibboleth.oidc.profile.core.OidcEventIds;
import net.shibboleth.shared.collection.Pair;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* An action that validates the requested response_type is (1) registered to the requesting RP (or accepted in the
@@ -124,13 +126,17 @@ public class ValidateResponseType extends AbstractOAuthAuthorizationResponseActi
final ResponseType requestedType = requestedResponseTypeLookupStrategy.apply(profileRequestContext);
- if (getMetadataContext() != null) {
- final Set<ResponseType> registeredTypes =
- getMetadataContext().getClientInformation().getMetadata().getResponseTypes();
- if (registeredTypes == null || registeredTypes.isEmpty() || !registeredTypes.contains(requestedType)) {
- log.warn("{} The response type {} is not registered for this RP", getLogPrefix(), requestedType);
- ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_RESPONSE_TYPE);
- return;
+ final OIDCMetadataContext metadataContext = getMetadataContext();
+ if (metadataContext != null) {
+ final OIDCClientInformation clientInformation = metadataContext.getClientInformation();
+ if (clientInformation != null && clientInformation.getOIDCMetadata() != null) {
+ final Set<ResponseType> registeredTypes =
+ clientInformation.getMetadata().getResponseTypes();
+ if (registeredTypes == null || registeredTypes.isEmpty() || !registeredTypes.contains(requestedType)) {
+ log.warn("{} The response type {} is not registered for this RP", getLogPrefix(), requestedType);
+ ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_RESPONSE_TYPE);
+ return;
+ }
}
} else {
final Map<String, UnregisteredClientPolicy> policies =
@@ -143,10 +149,13 @@ public class ValidateResponseType extends AbstractOAuthAuthorizationResponseActi
final Pair<Object, Boolean> enforcerResult =
unregisteredClientPolicyEnforcer.apply(requestedType == null ? "" : requestedType.toString(),
policies.get("response_type"));
- if (!enforcerResult.getSecond()) {
- log.warn("{} The response type {} is not compliant with the policy", getLogPrefix(), requestedType);
- ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_RESPONSE_TYPE);
- return;
+ if (enforcerResult != null) {
+ final Boolean validationResult = enforcerResult.getSecond();
+ if (validationResult == null || !validationResult.booleanValue()) {
+ log.warn("{} The response type {} is not compliant with the policy", getLogPrefix(), requestedType);
+ ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_RESPONSE_TYPE);
+ return;
+ }
}
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateScope.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateScope.java
index b29b78c9..105a3c04 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateScope.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/ValidateScope.java
@@ -20,25 +20,28 @@ import java.util.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.opensaml.messaging.context.BaseContext;
import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.context.ProfileRequestContext;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.oauth2.sdk.ResponseType;
import com.nimbusds.oauth2.sdk.Scope;
import com.nimbusds.openid.connect.sdk.OIDCScopeValue;
+import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseTokenClaimsContext;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.ClientInfoScopeLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultOIDCMetadataContextLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequestResponseTypeLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultRequestedScopeLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.OIDCAuthenticationResponseContextLookupFunction;
+import net.shibboleth.idp.plugin.oidc.op.token.support.TokenClaimsSet;
import net.shibboleth.oidc.profile.core.OidcEventIds;
import net.shibboleth.profile.context.navigate.RelyingPartyIdLookupFunction;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Action that validates requested and previously granted scopes are also registered in client metadata
@@ -85,12 +88,16 @@ public class ValidateScope extends AbstractOAuthAuthorizationResponseAction {
public ValidateScope() {
requestedScopeLookupStrategy = new DefaultRequestedScopeLookupFunction();
relyingPartyIdLookupStrategy = new RelyingPartyIdLookupFunction();
- allowedScopeLookupStrategy = new ClientInfoScopeLookupFunction().compose(
+ final Function<ProfileRequestContext,Scope> asls = new ClientInfoScopeLookupFunction().compose(
new DefaultOIDCMetadataContextLookupFunction());
+ assert asls != null;
+ allowedScopeLookupStrategy = asls;
mandatoryScopeLookupStrategy = prc -> null;
- tokenClaimsContextLookupStrategy =
+ final Function<ProfileRequestContext,OIDCAuthenticationResponseTokenClaimsContext> tccls =
new ChildContextLookup<>(OIDCAuthenticationResponseTokenClaimsContext.class).compose(
new OIDCAuthenticationResponseContextLookupFunction());
+ assert tccls != null;
+ tokenClaimsContextLookupStrategy = tccls;
}
/**
@@ -164,10 +171,13 @@ public class ValidateScope extends AbstractOAuthAuthorizationResponseAction {
final String clientId = relyingPartyIdLookupStrategy.apply(profileRequestContext);
+ final OIDCAuthenticationResponseContext oidcResponseContext = getOidcResponseContext();
+ assert oidcResponseContext != null;
// These come from a previous authorization grant (authz code or access/refresh token).
Scope previouslyGrantedScopes = null;
- if (getOidcResponseContext().getAuthorizationGrantClaimsSet() != null) {
- previouslyGrantedScopes = getOidcResponseContext().getAuthorizationGrantClaimsSet().getScope();
+ final TokenClaimsSet authzGrantClaimsSet = oidcResponseContext.getAuthorizationGrantClaimsSet();
+ if (authzGrantClaimsSet != null) {
+ previouslyGrantedScopes = authzGrantClaimsSet.getScope();
}
// These come from a request object or parameter. Absent by definition on the UserInfo endpoint.
@@ -243,16 +253,19 @@ public class ValidateScope extends AbstractOAuthAuthorizationResponseAction {
}
if (!requestedScopes.isEmpty()) {
- getOidcResponseContext().setScope(requestedScopes);
+ oidcResponseContext.setScope(requestedScopes);
}
if (reducedRequestedScopes) {
final OIDCAuthenticationResponseTokenClaimsContext tokenClaimsCtx =
tokenClaimsContextLookupStrategy.apply(profileRequestContext);
if (tokenClaimsCtx != null) {
- log.debug("{} Removing grant-encoded attributes due to reduction of requested scopes",
- getLogPrefix());
- tokenClaimsCtx.getParent().removeSubcontext(tokenClaimsCtx);
+ final BaseContext parentContext = tokenClaimsCtx.getParent();
+ if (parentContext != null) {
+ log.debug("{} Removing grant-encoded attributes due to reduction of requested scopes",
+ getLogPrefix());
+ parentContext.removeSubcontext(tokenClaimsCtx);
+ }
}
}
}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractBuildErrorResponseFromEvent.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractBuildErrorResponseFromEvent.java
index f1fcefd4..3b7d43fa 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractBuildErrorResponseFromEvent.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/AbstractBuildErrorResponseFromEvent.java
@@ -24,7 +24,6 @@ import org.opensaml.profile.context.EventContext;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.profile.context.navigate.CurrentOrPreviousEventLookup;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.nimbusds.oauth2.sdk.ErrorObject;
import com.nimbusds.oauth2.sdk.ErrorResponse;
@@ -32,6 +31,7 @@ import com.nimbusds.oauth2.sdk.http.HTTPResponse;
import net.shibboleth.idp.profile.AbstractProfileAction;
import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* This action is extended by error response actions. Action reads an event from the configured {@link EventContext}
@@ -120,7 +120,8 @@ public abstract class AbstractBuildErrorResponseFromEvent<T extends ErrorRespons
* @param profileRequestContext profile request context.
* @return ErrorResponse
*/
- protected abstract T buildErrorResponse(ErrorObject error, ProfileRequestContext profileRequestContext);
+ protected abstract T buildErrorResponse(@Nonnull final ErrorObject error,
+ @Nonnull final ProfileRequestContext profileRequestContext);
/** {@inheritDoc} */
@Override
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list