[java-idp-plugin-oidc-op-oidfed] 02/02: Improvements mainly for explicit registration request handling
Codeberg
noreply at shibboleth.net
Fri Oct 9 10:19:50 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository java-idp-plugin-oidc-op-oidfed.
View the commit online:
https://codeberg.org/Shibboleth/java-idp-plugin-oidc-op-oidfed/commit/97aced6a3b1b9642f4cc80799eb01be7e242ccc5
commit 97aced6a3b1b9642f4cc80799eb01be7e242ccc5
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Oct 9 13:19:20 2026 +0300
Improvements mainly for explicit registration request handling
- Improved content type validation: only validate the mime-type
- Copy the jwks from request to response as is, as mandated by the spec
- Map explicit registration error events better to the error messages
- Fixed some typos in the log messages
- Improve testing
---
.../ExplicitClientRegistrationRequestDecoder.java | 37 +++++++---
.../impl/AddExtensionsToClientInformation.java | 2 +-
.../impl/BuildExplicitRegistrationResponse.java | 10 +--
.../profile/impl/ValidateProvidedTrustChain.java | 2 +-
...videdEntityConfigurationValidationStrategy.java | 2 +-
...aultPreSelectedTrustChainIDsLookupStrategy.java | 7 +-
...entRegistrationRequestJWKSetLookupFunction.java | 35 ++++++---
.../META-INF/net.shibboleth.idp/postconfig.xml | 36 +++++++++
.../profile/flow/oidfed/RegistrationFlowTest.java | 86 ++++++++++++++++++++--
9 files changed, 177 insertions(+), 40 deletions(-)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ExplicitClientRegistrationRequestDecoder.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ExplicitClientRegistrationRequestDecoder.java
index 629195e..2345bc3 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ExplicitClientRegistrationRequestDecoder.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ExplicitClientRegistrationRequestDecoder.java
@@ -16,11 +16,14 @@ package net.shibboleth.idp.plugin.oidc.op.oidfed.decoding.impl;
import java.io.IOException;
import java.net.URI;
+import java.nio.charset.UnsupportedCharsetException;
import java.util.List;
+import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.apache.hc.core5.http.ContentType;
import org.opensaml.messaging.decoder.MessageDecodingException;
import org.slf4j.Logger;
@@ -42,6 +45,7 @@ import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.logic.ConstraintViolationException;
import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.StringSupport;
/**
* Message decoder decoding OpenID Federation Explicit Registration request {@link ExplicitClientRegistrationRequest}.
@@ -91,8 +95,8 @@ public class ExplicitClientRegistrationRequestDecoder
throw new MessageDecodingException("Could not parse request URI");
}
final String contentType = request.getContentType();
- if ("application/entity-statement+jwt".equals(contentType)) {
- final String query = httpRequest.getQuery();
+ if (ContentType.create("application/entity-statement+jwt").isSameMimeType(ContentType.parse(contentType))) {
+ final String query = StringSupport.trimOrNull(httpRequest.getBody());
if (query != null) {
try {
assert objectMapper != null;
@@ -107,21 +111,30 @@ public class ExplicitClientRegistrationRequestDecoder
}
}
throw new MessageDecodingException("Could not deserialize entity configuration");
- } else if ("application/trust-chain+json".equals(contentType)) {
- final TypeReference<List<String>> typeReference = new TypeReference<List<String>>() {};
- final List<String> strings = objectMapper.readValue(httpRequest.getQuery(), typeReference);
- assert strings != null; assert objectMapper != null;
- final List<EntityStatement<?>> trustChain =
- EntityStatementHelper.deserializeTrustChain(strings, objectMapper);
- if (trustChain == null) {
- throw new MessageDecodingException("Could not deserialize trust chain");
+ } else if (ContentType.create("application/trust-chain+json").isSameMimeType(
+ ContentType.parse(contentType))) {
+ final String body = StringSupport.trimOrNull(httpRequest.getBody());
+ if (body != null) {
+ final TypeReference<List<String>> typeReference = new TypeReference<List<String>>() {};
+ final List<String> rawStrings = objectMapper.readValue(body, typeReference);
+ if (rawStrings == null) {
+ throw new MessageDecodingException("Could not deserialize trust chain");
+ }
+ final List<String> strings = rawStrings.stream().filter(Objects::nonNull).toList();
+ assert strings != null; assert objectMapper != null;
+ final List<EntityStatement<?>> trustChain =
+ EntityStatementHelper.deserializeTrustChain(strings, objectMapper);
+ if (trustChain == null) {
+ throw new MessageDecodingException("Could not deserialize trust chain");
+ }
+ return new ExplicitClientRegistrationRequest(uri, trustChain);
}
- return new ExplicitClientRegistrationRequest(uri, trustChain);
+ throw new MessageDecodingException("Could not deserialize trust chain");
} else {
log.warn("Unexpected content type {}", contentType);
throw new MessageDecodingException("Unexpected content type: " + contentType);
}
- } catch (final IOException e) {
+ } catch (final IOException | UnsupportedCharsetException e) {
log.error("Could not create HTTP request from the request", e);
throw new MessageDecodingException(e);
}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AddExtensionsToClientInformation.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AddExtensionsToClientInformation.java
index 979ab13..456cdf8 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AddExtensionsToClientInformation.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AddExtensionsToClientInformation.java
@@ -141,7 +141,7 @@ public class AddExtensionsToClientInformation extends AbstractProfileAction {
final OIDCClientRegistrationResponseContext oidcResponseCtx =
oidcResponseContextLookupStrategy.apply(profileRequestContext);
if (oidcResponseCtx == null || oidcResponseCtx.getClientInformation() == null) {
- log.debug("{} No OIDC client informationt could be resolved with this profile request",
+ log.debug("{} No OIDC client information could be resolved with this profile request",
getLogPrefix());
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
return false;
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildExplicitRegistrationResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildExplicitRegistrationResponse.java
index 36aa568..c305782 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildExplicitRegistrationResponse.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildExplicitRegistrationResponse.java
@@ -17,6 +17,7 @@ package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
import java.time.Instant;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import java.util.function.Function;
import javax.annotation.Nonnull;
@@ -29,7 +30,6 @@ import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
import org.slf4j.Logger;
-import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
@@ -60,7 +60,7 @@ public class BuildExplicitRegistrationResponse extends AbstractBuildEntityStatem
@Nonnull private Function<ProfileRequestContext,OIDCClientRegistrationResponseContext> oidcResponseContextLookupStrategy;
/** Strategy used to locate the JWK set to be included in the response entity statement. */
- @Nonnull private Function<ProfileRequestContext,JWKSet> jwkSetLookupStrategy;
+ @Nonnull private Function<ProfileRequestContext,Map<String,Object>> jwkSetLookupStrategy;
/** Strategy used to lookup the trust chain context. */
@Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
@@ -112,7 +112,7 @@ public class BuildExplicitRegistrationResponse extends AbstractBuildEntityStatem
*
* @param strategy lookup strategy
*/
- public void setJwkSetLookupStrategy(@Nonnull final Function<ProfileRequestContext,JWKSet> strategy) {
+ public void setJwkSetLookupStrategy(@Nonnull final Function<ProfileRequestContext,Map<String,Object>> strategy) {
checkSetterPreconditions();
jwkSetLookupStrategy = Constraint.isNotNull(strategy, "JWK set loookup strategy cannot be null");
}
@@ -189,13 +189,13 @@ public class BuildExplicitRegistrationResponse extends AbstractBuildEntityStatem
builder.claim("metadata",
CollectionSupport.singletonMap("openid_relying_party", clientInformation.toJSONObject()));
- final JWKSet jwkSet = jwkSetLookupStrategy.apply(profileRequestContext);
+ final Map<String,Object> jwkSet = jwkSetLookupStrategy.apply(profileRequestContext);
if (jwkSet == null) {
log.error("{} Coud not resolve JWK set to be included in the response statement", getLogPrefix());
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
return false;
}
- builder.claim("jwks", jwkSet.toJSONObject(true));
+ builder.claim("jwks", CollectionSupport.copyToMap(jwkSet));
final Instant expirationTime = trustChainContext.getSelectedMetadataExpiration();
if (expirationTime == null) {
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java
index ee24179..0b931f9 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java
@@ -160,7 +160,7 @@ public class ValidateProvidedTrustChain extends AbstractTrustChainResolutionActi
return false;
}
if (ignoreProvidedTrustChainCondition.test(profileRequestContext)) {
- log.debug("{} Provided trust chains are configurd to be ignored, nothing to do", getLogPrefix());
+ log.debug("{} Provided trust chains are configured to be ignored, nothing to do", getLogPrefix());
return false;
}
if (trustChain == null) {
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/logic/DefaultProvidedEntityConfigurationValidationStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/logic/DefaultProvidedEntityConfigurationValidationStrategy.java
index 936497b..44875c8 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/logic/DefaultProvidedEntityConfigurationValidationStrategy.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/logic/DefaultProvidedEntityConfigurationValidationStrategy.java
@@ -86,7 +86,7 @@ public class DefaultProvidedEntityConfigurationValidationStrategy extends Abstra
return true;
}
} catch (final MetadataCacheException e) {
- log.debug("{} Exception catched when validating entty configuration", e);
+ log.debug("Exception catched when validating entity configuration", e);
}
} else {
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultPreSelectedTrustChainIDsLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultPreSelectedTrustChainIDsLookupStrategy.java
index 4ed4ff6..361bdfe 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultPreSelectedTrustChainIDsLookupStrategy.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultPreSelectedTrustChainIDsLookupStrategy.java
@@ -19,6 +19,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
+import java.util.function.Supplier;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -92,7 +93,7 @@ public class DefaultPreSelectedTrustChainIDsLookupStrategy extends AbstractIdent
return Optional.ofNullable(profileIdLookupStrategy.apply(input))
.map(profileId -> profileSpecificStrategies.get(profileId))
.map(function -> function.apply(input))
- .orElse(defaultValue(input));
+ .orElseGet(defaultValue(input));
}
/**
@@ -101,8 +102,8 @@ public class DefaultPreSelectedTrustChainIDsLookupStrategy extends AbstractIdent
* @param input profile request context
* @return trust chain IDs
*/
- private List<String> defaultValue(@Nullable final ProfileRequestContext input) {
- return Optional.ofNullable(input)
+ private Supplier<List<String>> defaultValue(@Nullable final ProfileRequestContext input) {
+ return () -> Optional.ofNullable(input)
.filter(prc -> prc.getOutboundMessageContext() != null)
.map(prc -> prc.ensureOutboundMessageContext())
.filter(msgCtx -> msgCtx.containsSubcontext(OIDCAuthenticationResponseContext.class))
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestJWKSetLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestJWKSetLookupFunction.java
index 9152b6f..916a488 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestJWKSetLookupFunction.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/ExplicitClientRegistrationRequestJWKSetLookupFunction.java
@@ -14,31 +14,40 @@
package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate;
+import java.text.ParseException;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import org.opensaml.messaging.context.navigate.ContextDataLookupFunction;
import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
import com.nimbusds.jose.jwk.JWKSet;
import net.shibboleth.oidfed.messaging.impl.ExplicitClientRegistrationRequest;
import net.shibboleth.oidfed.metadata.EntityConfiguration;
import net.shibboleth.oidfed.metadata.EntityStatement;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
- * A function that returns {@link JWKSet} from the entity configuration in the explicit registration request.
+ * A function that returns {@link JWKSet} as Map from the entity configuration in the explicit registration request.
*/
@ThreadSafe
public class ExplicitClientRegistrationRequestJWKSetLookupFunction
- implements ContextDataLookupFunction<ProfileRequestContext, JWKSet> {
+ implements ContextDataLookupFunction<ProfileRequestContext, Map<String,Object>> {
+
+ /** Class logger. */
+ @Nonnull
+ private final Logger log = LoggerFactory.getLogger(ExplicitClientRegistrationRequestJWKSetLookupFunction.class);
/** {@inheritDoc} */
@Nullable
- public JWKSet apply(@Nullable final ProfileRequestContext input) {
+ public Map<String,Object> apply(@Nullable final ProfileRequestContext input) {
return Optional.ofNullable(input)
.map(profileRequesContext -> profileRequesContext.getInboundMessageContext())
.map(messageContext -> messageContext.getMessage())
@@ -49,20 +58,26 @@ public class ExplicitClientRegistrationRequestJWKSetLookupFunction
}
/**
- * Get the JSON Web Key Set from the explicit registration request.
+ * Get the JSON Web Key Set as Map from the explicit registration request.
*
* @param request explicit registration request
- * @return the JWKSet, or null if it cannot be parsed
+ * @return the contents of jwks, or null if it cannot be parsed
*/
- @Nullable protected JWKSet getJWKSet(@Nullable final ExplicitClientRegistrationRequest request) {
+ @Nullable protected Map<String,Object> getJWKSet(@Nullable final ExplicitClientRegistrationRequest request) {
if (request == null) {
return null;
}
final EntityConfiguration entityConfiguration = request.getEntityConfiguration();
- if (entityConfiguration != null) {
- return entityConfiguration.getParsedPayload().getJwks();
+ try {
+ if (entityConfiguration != null) {
+ return entityConfiguration.getJwt().getJWTClaimsSet().getJSONObjectClaim("jwks");
+ }
+ final List<EntityStatement<?>> trustChain = request.getTrustChain();
+ return trustChain != null && !trustChain.isEmpty() ?
+ trustChain.get(0).getJwt().getJWTClaimsSet().getJSONObjectClaim("jwks") : null;
+ } catch (final ParseException e) {
+ log.error("Could not parse jwks from the JWT claims set", e);
}
- final List<EntityStatement<?>> trustChain = request.getTrustChain();
- return trustChain != null && !trustChain.isEmpty() ? trustChain.get(0).getParsedPayload().getJwks() : null;
+ return null;
}
}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index c8a0eb5..be9d125 100644
--- a/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -62,6 +62,42 @@
</key>
<bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_client" c:_1="No acceptable trust chains could be resolved for the client" c:_2="401" />
</entry>
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.oidfed.profile.OidFederationEventIds.INVALID_PROVIDED_TRUST_CHAIN"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_client" c:_1="No acceptable trust chains could be resolved for the client" c:_2="401" />
+ </entry>
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.oidfed.profile.OidFederationEventIds.MISSING_MANDATORY_PROVIDED_TRUST_CHAIN"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_client" c:_1="No mandatory trust chains could be resolved for the client" c:_2="401" />
+ </entry>
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.idp.authn.AuthnEventIds.INVALID_CREDENTIALS"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_client" c:_1="No acceptable entity configuration could be resolved for the client" c:_2="401" />
+ </entry>
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.oidfed.profile.OidFederationEventIds.INVALID_METADATA_POLICY"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_client" c:_1="No acceptable metadata policy could be resolved for the client" c:_2="401" />
+ </entry>
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.oidfed.profile.OidFederationEventIds.INVALID_METADATA_AGAINST_POLICY"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_client" c:_1="No acceptable metadata could be resolved for the client against the metadata policy" c:_2="401" />
+ </entry>
+ <entry>
+ <key>
+ <util:constant static-field="net.shibboleth.oidfed.profile.OidFederationEventIds.INVALID_TRUST_CHAIN_AGAINST_CONSTRAINTS"/>
+ </key>
+ <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_client" c:_1="No acceptable trust chains could be resolved for the client against the policy constraints" c:_2="401" />
+ </entry>
</map>
</property>
</bean>
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
index eb9f820..fd79083 100644
--- a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
@@ -86,6 +86,21 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
assertErrorCode(result, "invalid_request");
}
+ @Test
+ public void testNullEntityConfiguration() throws Exception {
+ request.setMethod("POST");
+ request.setContentType("application/entity-statement+jwt");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testNullStringEntityConfiguration() throws Exception {
+ setRequest("POST", "null", "application/entity-statement+jwt");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ }
+
@Test
public void testEmptyEntityConfiguration() throws Exception {
setRequest("POST", "", "application/entity-statement+jwt");
@@ -105,7 +120,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
verify(federationHttpClient, times(0)).executeOpen(any(),
argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
- assertErrorCode(result, "invalid_request");
+ assertErrorCode(result, "invalid_client");
}
@Test
@@ -129,6 +144,18 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
verifyAuthorizeEndpoint(clientId, redirectUri);
}
+ @Test
+ public void testValidEntityConfigurationWithCharsetInContentType() throws Exception {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClient(clientId);
+ setRequest("POST", explicitRegistrationRequest(clientId), "application/entity-statement+jwt;charset=UTF-8");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ assertResponseStatement(parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ verifyAuthorizeEndpoint(clientId, redirectUri);
+ }
+
@Test
public void testValidEntityConfiguration_emptyMetadataPolicyCrit() throws Exception {
final String clientId = uniqueClientId();
@@ -152,7 +179,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
verify(federationHttpClient, times(0)).executeOpen(any(),
argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
- assertErrorCode(result, "invalid_request");
+ assertErrorCode(result, "invalid_client");
}
@Test
@@ -295,6 +322,35 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
+ "\", \"" + trustedAnchorConfiguration() + "\"]";
setRequest("POST", trustChain, "application/trust-chain+json");
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_client");
+ }
+
+ @Test
+ public void testNullTrustChain() throws Exception {
+ request.setMethod("POST");
+ request.setContentType("application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testNullStringTrustChain() throws Exception {
+ setRequest("POST", "null", "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testEmptyTrustChain() throws Exception {
+ setRequest("POST", "", "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ }
+
+ @Test
+ public void testNullMememberTrustChain() throws Exception {
+ setRequest("POST", "[null,null,null]", "application/trust-chain+json");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertErrorCode(result, "invalid_request");
}
@@ -314,6 +370,22 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
verifyAuthorizeEndpoint(clientId, redirectUri);
}
+ @Test
+ public void testValidTrustChainWithCharsetInContentType() throws Exception {
+ final String clientId = uniqueClientId();
+ final String trustChain = "[\"" + explicitRegistrationRequest(clientId) + "\", \"" +
+ subordinateStatement(clientId, Map.of("openid_relying_party", new OIDCClientMetadata().toJSONObject()))
+ + "\", \"" + trustedAnchorConfiguration() + "\"]";
+ setRequest("POST", trustChain, "application/trust-chain+json;charset=UTF-8");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(super.subordinateStatementUrl(anchorFetchEndpoint, clientId))), any());
+ assertResponseStatement(parseSuccessResponse(result, ExplicitClientRegistrationResponse.class), clientId);
+ verifyAuthorizeEndpoint(clientId, redirectUri);
+ }
+
@Test
public void testValidTrustChain_resolveApi() throws Exception {
final String clientId = uniqueClientId();
@@ -360,7 +432,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
Map.of("max_path_length", Integer.valueOf(0))) + "\", \"" + trustedAnchorConfiguration() + "\"]";
setRequest("POST", trustChain, "application/trust-chain+json");
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- assertErrorCode(result, "invalid_request");
+ assertErrorCode(result, "invalid_client");
}
@Test
@@ -377,7 +449,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
Map.of("max_path_length", Integer.valueOf(2))) + "\", \"" + trustedAnchorConfiguration() + "\"]";
setRequest("POST", trustChain, "application/trust-chain+json");
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- assertErrorCode(result, "invalid_request");
+ assertErrorCode(result, "invalid_client");
}
@Test
@@ -406,7 +478,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
"\", \"" + trustedAnchorConfiguration() + "\"]";
setRequest("POST", trustChain, "application/trust-chain+json");
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- assertErrorCode(result, "invalid_request");
+ assertErrorCode(result, "invalid_client");
}
@Test
@@ -459,7 +531,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
new OIDCClientMetadata().toJSONObject())) + "\", \"" + trustedAnchorConfiguration() + "\"]";
setRequest("POST", trustChain, "application/trust-chain+json");
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- assertErrorCode(result, "invalid_request");
+ assertErrorCode(result, "invalid_client");
}
@Test
@@ -478,7 +550,7 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
verify(federationHttpClient, times(0)).executeOpen(any(),
argThat(new RequestUriMatcher(super.subordinateStatementUrl(anchorFetchEndpoint, clientId))), any());
- assertErrorCode(result, "invalid_request");
+ assertErrorCode(result, "invalid_client");
}
@Test
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list