[java-idp-plugin-oidc-rp] branch main updated: Add a client (RP proxy) metadata resolution step
Phil Smart
philip.smart at jisc.ac.uk
Fri Jan 14 16:59:03 UTC 2022
This is an automated email from the git hooks/post-receive script.
philsmart pushed a commit to branch main
in repository java-idp-plugin-oidc-rp.
View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-oidc-rp.git;a=commit;h=b007d40b0b7a7b92f84d61962e9ef27a6e29a23b
The following commit(s) were added to refs/heads/main by this push:
new b007d40 Add a client (RP proxy) metadata resolution step
b007d40 is described below
commit b007d40b0b7a7b92f84d61962e9ef27a6e29a23b
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Jan 14 16:58:53 2022 +0000
Add a client (RP proxy) metadata resolution step
- Resolve client metadata appropriate for (registered with) the current
authenticating authority (OP)
- Use a custom issuer field/claim added to the client metadata
- Created some near duplicates of resolver classes in commons. Needs
refactoring.
- Improve AddAuthz request construction to consider both provider and
client metadata
---
.../authn/oidc/rp/context/OIDCMetadataContext.java | 59 +++++++
.../plugin/authn/oidc/rp/impl/AddAuthzRequest.java | 45 ++++--
.../impl/FilesystemClientInformationResolver.java | 171 +++++++++++++++++++++
.../metadata/impl/OIDCMetadataLookupHandler.java | 130 ++++++++++++++++
.../impl/OIDCProviderMetadataLookupHandler.java | 1 +
.../META-INF/net.shibboleth.idp/postconfig.xml | 38 ++++-
.../oidc-relying-party-authn-beans.xml | 20 ++-
.../oidc-relying-party-authn-flow.xml | 6 +-
.../rp/conf/authn/clientinfo-resolver-system.xml | 32 ++++
.../authn/providermetadata-resolver-system.xml | 2 +-
.../oidc/rp/impl/AuthorizationControllerTest.java | 4 +-
.../conf/authn/oidc-clientinfo-resolvers.xml | 23 +++
.../src/test/resources/metadata/oidc-clients.json | 26 ++++
13 files changed, 535 insertions(+), 22 deletions(-)
diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OIDCMetadataContext.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OIDCMetadataContext.java
new file mode 100644
index 0000000..6bafcbb
--- /dev/null
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OIDCMetadataContext.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.plugin.authn.oidc.rp.context;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+
+/**
+ * Subcontext carrying information on metadata of the relying party. This
+ * context appears as a subcontext of the
+ * {@link org.opensaml.messaging.context.MessageContext} that carries the actual
+ * OIDC request message, in such cases the metadata carried herein applies to
+ * the issuer of that message.
+ *
+ * This context is just a placeholder for the final solution. At first phase we
+ * use only redirect uris.
+ */
+public class OIDCMetadataContext extends BaseContext {
+
+ /** The client information. */
+ @Nullable private OIDCClientInformation clientInformation;
+
+ /**
+ * Set the client information.
+ *
+ * @return The client information.
+ */
+ @Nullable
+ public OIDCClientInformation getClientInformation() {
+ return clientInformation;
+ }
+
+ /**
+ * Set the client information.
+ *
+ * @param information The client information.
+ */
+ public void setClientInformation(@Nullable final OIDCClientInformation information) {
+ clientInformation = information;
+ }
+}
\ No newline at end of file
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddAuthzRequest.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddAuthzRequest.java
index cfa5255..4d7511c 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddAuthzRequest.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddAuthzRequest.java
@@ -36,6 +36,8 @@ import com.nimbusds.oauth2.sdk.id.ClientID;
import net.shibboleth.idp.authn.AbstractAuthenticationAction;
import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.idp.plugin.authn.oidc.rp.context.OIDCMetadataContext;
+import net.shibboleth.idp.plugin.authn.oidc.rp.messaging.context.OIDCProviderMetadataContext;
import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.idp.profile.context.RelyingPartyContext;
import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
@@ -67,6 +69,12 @@ public class AddAuthzRequest extends AbstractAuthenticationAction {
/** Applicable profile configuration. */
@Nullable private OIDCAuthorizationConfiguration profileConfiguration;
+ /** The metadata belonging to the client registered with the current OpenID Provider.*/
+ @Nullable private OIDCMetadataContext clientMetadata;
+
+ /** The metadata belonging to the OpenID Provider.*/
+ @Nullable private OIDCProviderMetadataContext providerMetadata;
+
/** Constructor.*/
public AddAuthzRequest() {
// Fool the parent class into looking above instead of below the PRC for the context.
@@ -114,6 +122,20 @@ public class AddAuthzRequest extends AbstractAuthenticationAction {
return false;
}
+ final MessageContext inboundMessageCtx = profileRequestContext.getInboundMessageContext();
+ clientMetadata = inboundMessageCtx.getSubcontext(OIDCMetadataContext.class);
+ if (clientMetadata == null) {
+ log.debug("{} Inbound message context did not contain client metadata", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+ providerMetadata = inboundMessageCtx.getSubcontext(OIDCProviderMetadataContext.class);
+ if (providerMetadata == null) {
+ log.debug("{} Inbound message context did not contain provider metadata", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+ return false;
+ }
+
outboundMessageCtx.setMessage(null);
return true;
@@ -126,19 +148,16 @@ public class AddAuthzRequest extends AbstractAuthenticationAction {
log.debug("{} Building AuthzRequest for upstream OP ({})",
getLogPrefix(), authenticationContext.getAuthenticatingAuthority());
- try {
- final OIDCAuthenticationRequest request = new OIDCAuthenticationRequest(new ClientID("clientID"));
- // FIXME: This needs to be dynamic, is a demo for now
- request.setResponseType(ResponseType.CODE);
- request.setEndpointURI(new URI("https://somewhere.com/oauth2/authz"));
- request.setRedirectURI(new URI("https://localhost:8080/callback"));
-
- log.debug("{} Built authorization request for endpoint '{}'",getLogPrefix(), request.getEndpointURI());
- profileRequestContext.getOutboundMessageContext().setMessage(request);
- } catch (URISyntaxException e) {
- log.error("{} Unable to create authorization request for downstream OP '{}'", getLogPrefix(), "OP");
-
- }
+
+ final OIDCAuthenticationRequest request = new OIDCAuthenticationRequest(clientMetadata.getClientInformation().getID());
+
+ request.setResponseType(ResponseType.CODE);
+ request.setEndpointURI(providerMetadata.getProviderInformation().getAuthorizationEndpointURI());
+ request.setRedirectURI(clientMetadata.getClientInformation().getMetadata().getRedirectionURI());
+
+ log.debug("{} Built authorization request for endpoint '{}'",getLogPrefix(), request.getEndpointURI());
+ profileRequestContext.getOutboundMessageContext().setMessage(request);
+
}
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/metadata/impl/FilesystemClientInformationResolver.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/metadata/impl/FilesystemClientInformationResolver.java
new file mode 100644
index 0000000..524ab13
--- /dev/null
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/metadata/impl/FilesystemClientInformationResolver.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Timer;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.Resource;
+
+import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.id.Issuer;
+import com.nimbusds.oauth2.sdk.util.JSONArrayUtils;
+import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+
+import net.minidev.json.JSONArray;
+import net.minidev.json.JSONObject;
+import net.shibboleth.oidc.metadata.RefreshableClientInformationResolver;
+import net.shibboleth.oidc.metadata.criterion.IssuerIDCriterion;
+import net.shibboleth.oidc.metadata.impl.AbstractFileOIDCEntityResolver;
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+/**
+ * A client metadata provider that pulls metadata from a file on the local filesystem.
+ *
+ * <p>The client information returned is determined from the 'issuer' custom claim.</p>
+ *
+ */
+public class FilesystemClientInformationResolver extends AbstractFileOIDCEntityResolver<Issuer, OIDCClientInformation>
+ implements RefreshableClientInformationResolver {
+
+ /** Class logger. */
+ private final Logger log = LoggerFactory.getLogger(FilesystemClientInformationResolver.class);
+
+ /**
+ * Constructor.
+ *
+ * @param metadata the metadata file
+ *
+ * @throws IOException If the metedata cannot be loaded.
+ */
+ public FilesystemClientInformationResolver(
+ @Nonnull @ParameterName(name="metadata") final Resource metadata) throws IOException {
+ super(metadata);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param metadata the metadata file
+ * @param backgroundTaskTimer timer used to refresh metadata in the background
+ *
+ * @throws IOException If the metedata cannot be loaded.
+ */
+ public FilesystemClientInformationResolver(@Nullable final Timer backgroundTaskTimer,
+ @Nonnull final Resource metadata) throws IOException {
+ super(backgroundTaskTimer, metadata);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Iterable<OIDCClientInformation> resolve(final CriteriaSet criteria) throws ResolverException {
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
+ ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+ final IssuerIDCriterion issuerIdCriterion = criteria.get(IssuerIDCriterion.class);
+ if (issuerIdCriterion == null || issuerIdCriterion.getIssuerID() == null) {
+ log.trace("No issuer ID criteria found, returning all");
+ return updateKeys(getBackingStore().getOrderedInformation());
+ }
+ // TODO: support other criterion
+ return updateKeys(lookupIdentifier(issuerIdCriterion.getIssuerID()));
+ }
+
+ /**
+ * Updates the key set in the given list of OIDC client informations. The configured remote JWK set cache is
+ * exploited.
+ *
+ * @param clientInformations The OIDC client informations whose keys are going to be updated.
+ *
+ * @return The OIDC client informations, containing contents of getJWKSetURI() in getJWKSet().
+ */
+ protected List<OIDCClientInformation> updateKeys(final List<OIDCClientInformation> clientInformations) {
+ final List<OIDCClientInformation> result = new ArrayList<>();
+ for (final OIDCClientInformation clientInformation : clientInformations) {
+ result.add(clientInformation);
+ }
+ return result;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public OIDCClientInformation resolveSingle(@Nullable final CriteriaSet criteria) throws ResolverException {
+ final Iterable<OIDCClientInformation> iterable = resolve(criteria);
+ if (iterable != null) {
+ final Iterator<OIDCClientInformation> 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
+ protected List<OIDCClientInformation> parse(@Nonnull final byte[] bytes) throws ParseException {
+ final String rawString = new String(bytes);
+ try {
+ final OIDCClientInformation single = OIDCClientInformation.parse(JSONObjectUtils.parse(rawString));
+ log.debug("Found single client information from the file");
+ return Arrays.asList(single);
+ } catch (final ParseException e) {
+ log.debug("Could not parse single client information from the file, checking for array");
+ }
+ try {
+ final JSONArray parsedArray = JSONArrayUtils.parse(rawString);
+ final List<OIDCClientInformation> result = new ArrayList<OIDCClientInformation>();
+ for (final Object object : parsedArray) {
+ final OIDCClientInformation client = OIDCClientInformation.parse((JSONObject) object);
+ result.add(client);
+ }
+ return result;
+ } catch (final ParseException e) {
+ throw new ParseException("Could not parse a single or an array of OIDC client information object(s).");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected Issuer getKey(@Nonnull final OIDCClientInformation value) {
+ final Object issuerObject = value.getMetadata().getCustomField("issuer");
+ if (issuerObject instanceof String) {
+ return new Issuer((String)issuerObject);
+ }
+ throw new IllegalArgumentException("Client information metadata does not contain an issuer");
+ }
+}
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/metadata/impl/OIDCMetadataLookupHandler.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/metadata/impl/OIDCMetadataLookupHandler.java
new file mode 100644
index 0000000..aff7fdc
--- /dev/null
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/metadata/impl/OIDCMetadataLookupHandler.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.handler.AbstractMessageHandler;
+import org.opensaml.messaging.handler.MessageHandlerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.nimbusds.oauth2.sdk.id.Issuer;
+import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+
+import net.shibboleth.idp.plugin.authn.oidc.rp.context.OIDCMetadataContext;
+import net.shibboleth.oidc.metadata.ClientInformationResolver;
+import net.shibboleth.oidc.metadata.criterion.IssuerIDCriterion;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+/**
+ * Handler for inbound OIDC protocol messages that attempts to locate OIDC metadata for a RP, and attaches it with a
+ * {@link OIDCMetadataContext} as a child of a pre-existing instance of {@link MessageContext}.
+ */
+public class OIDCMetadataLookupHandler extends AbstractMessageHandler {
+
+ /** Logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(OIDCMetadataLookupHandler.class);
+
+ /** Resolver used to look up OIDC client information. */
+ @NonnullAfterInit private ClientInformationResolver clientResolver;
+
+ /** Strategy used to obtain the issuer value for the authorization request. */
+ @Nonnull
+ private Function<MessageContext, String> issuerLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public OIDCMetadataLookupHandler() {
+ issuerLookupStrategy = new DefaultIssuerIDLookupFunction();
+ }
+
+ /**
+ * Set the strategy used to locate the issuer (downstream OP) for the request.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setIssuerLookupStrategy(@Nonnull final Function<MessageContext, String> strategy) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ issuerLookupStrategy =
+ Constraint.isNotNull(strategy, "IssuerLookupStrategy lookup strategy cannot be null");
+ }
+
+ /**
+ * Set the {@link ClientInformationResolver} to use.
+ *
+ * @param resolver The resolver to use.
+ */
+ public void setClientInformationResolver(@Nonnull final ClientInformationResolver resolver) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ clientResolver = Constraint.isNotNull(resolver, "ClientInformationResolver cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (clientResolver == null) {
+ throw new ComponentInitializationException("ClientInformationResolver cannot be null");
+ }
+ }
+
+ //TODO test if no client returned
+ /** {@inheritDoc} */
+ @Override
+ protected void doInvoke(@Nonnull final MessageContext messageContext) throws MessageHandlerException {
+ ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
+ // Resolve issuer from inbound message
+ final String issuerString = issuerLookupStrategy.apply(messageContext);
+ if (issuerString == null) {
+ log.warn("{} Issuer not found, client information can not be resolved", getLogPrefix());
+ return;
+ }
+ // Resolve client metadata for given issuer
+ final IssuerIDCriterion issuerCriterion = new IssuerIDCriterion(new Issuer(issuerString));
+ final CriteriaSet criteria = new CriteriaSet(issuerCriterion);
+ try {
+ final OIDCClientInformation clientInformation = clientResolver.resolveSingle(criteria);
+ if (clientInformation == null) {
+ log.debug("{} No client information returned for issuer {}", getLogPrefix(), issuerString);
+ return;
+ }
+ log.debug("{} Resolved client information for client '{}'", getLogPrefix(), clientInformation.getID());
+ final OIDCMetadataContext oidcCtx = new OIDCMetadataContext();
+ oidcCtx.setClientInformation(clientInformation);
+ messageContext.addSubcontext(oidcCtx);
+ // Based on that info we know 1) client is valid 2) we know valid
+ // redirect uris
+ log.debug("{} {} added to MessageContext as child of {}", getLogPrefix(),
+ OIDCMetadataContext.class.getName(), messageContext.getClass().getName());
+ } catch (final ResolverException e) {
+ log.error("{} ResolverException thrown during client information lookup", getLogPrefix(), e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/metadata/impl/OIDCProviderMetadataLookupHandler.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/metadata/impl/OIDCProviderMetadataLookupHandler.java
index 42f78d8..bf413c2 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/metadata/impl/OIDCProviderMetadataLookupHandler.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/metadata/impl/OIDCProviderMetadataLookupHandler.java
@@ -29,6 +29,7 @@ import net.shibboleth.utilities.java.support.resolver.ResolverException;
* {@link OIDCMetadataContext} as a child of a pre-existing instance of {@link MessageContext}.
*/
//TODO should this be conflated with the OIDCMetadataLookupHandler service
+//TODO is commons the correct place to put this?
public class OIDCProviderMetadataLookupHandler extends AbstractMessageHandler {
/** Logger. */
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index ef18587..c5fe8cc 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -123,7 +123,7 @@
OR <value>classpath:/conf/oidc-providermetadata-resolvers.xml</value>
</util:list> -->
<util:list id="shibboleth.DefaultProviderMetadataResolverResources">
- <value>%{idp.home}/conf/authn/oidc-providermetadata-resolvers.xml</value>
+ <value>%{idp.home}/conf/authn/oidc-providermetadata-resolvers.xml</value> <!-- should be a conditional:? -->
</util:list>
<!-- Auto-append system config file to resource set. -->
<bean id ="ExtendedProviderMetadataResolverResources" class="net.shibboleth.ext.spring.factory.CombiningListFactoryBean"
@@ -135,6 +135,42 @@
</util:list>
</property>
</bean>
+
+
+ <!-- OIDC client information resolver service beans. -->
+
+ <!-- TODO add this back? depends-on="shibboleth.AttributeResolverService"-->
+
+ <bean id="shibboleth.oidc.rp.ClientInformationResolverService"
+ class="net.shibboleth.ext.spring.service.ReloadableSpringService"
+ p:serviceConfigurations-ref="ExtendedClientInformationResolverResources"
+ p:failFast="%{idp.service.clientinfo.failFast:%{idp.service.failFast:false}}"
+ p:reloadCheckDelay="%{idp.service.clientinfo.checkInterval:PT0S}"
+ p:beanPostProcessors-ref="shibboleth.IdentifiableBeanPostProcessor"
+ p:beanFactoryPostProcessors-ref="shibboleth.PropertySourcesPlaceholderConfigurer">
+ <constructor-arg name="claz"
+ value="net.shibboleth.oidc.metadata.ClientInformationResolver" />
+ <constructor-arg name="strategy">
+ <bean class="net.shibboleth.oidc.profile.spring.relyingparty.metadata.impl.ClientInformationResolverServiceStrategy" />
+ </constructor-arg>
+ </bean>
+ <util:list id="shibboleth.DefaultClientInformationResolverResources">
+ <value>%{idp.home}/conf/authn/oidc-clientinfo-resolvers.xml</value> <!-- should be a conditional:? -->
+ </util:list>
+ <!-- Auto-append system config file to resource set. -->
+ <bean id ="ExtendedClientInformationResolverResources" class="net.shibboleth.ext.spring.factory.CombiningListFactoryBean"
+ p:firstList="#{getObject('%{idp.service.clientinfo.resources:shibboleth.ClientInformationResolverResources}'.trim()) ?:
+ getObject('shibboleth.DefaultClientInformationResolverResources')}">
+ <property name="secondList">
+ <util:list >
+ <value>classpath:/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/clientinfo-resolver-system.xml</value>
+ </util:list>
+ </property>
+ </bean>
+
+ <bean id="shibboleth.oidc.rp.ClientInformationResolver"
+ class="net.shibboleth.oidc.metadata.impl.ReloadingRelyingPartyClientInformationProvider"
+ c:resolverService-ref="shibboleth.oidc.rp.ClientInformationResolverService" />
</beans>
\ No newline at end of file
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
index 89c8eb9..4cb940c 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
@@ -70,7 +70,7 @@
</property>
</bean>
- <bean id="OIDCMetadataLookup" parent="NestedWebFlowMessageHandlerAdaptor"
+ <bean id="OIDCProviderMetadataLookup" parent="NestedWebFlowMessageHandlerAdaptor"
scope="prototype" c:executionDirection="INBOUND">
<constructor-arg name="messageHandler">
<bean class="net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl.OIDCProviderMetadataLookupHandler" scope="prototype">
@@ -84,6 +84,20 @@
</constructor-arg>
</bean>
+ <bean id="OIDCClientMetadataLookup" parent="NestedWebFlowMessageHandlerAdaptor"
+ scope="prototype" c:executionDirection="INBOUND">
+ <constructor-arg name="messageHandler">
+ <bean class="net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl.OIDCMetadataLookupHandler" scope="prototype">
+ <property name="clientInformationResolver">
+ <ref bean="shibboleth.oidc.rp.ClientInformationResolver" />
+ </property>
+ <!-- <property name="clientIDLookupStrategy">
+ <ref bean="shibboleth.oidc.rp.ClientIDLookupStrategy" />
+ </property> -->
+ </bean>
+ </constructor-arg>
+ </bean>
+
<bean id="shibboleth.oidc.rp.IssuerIDLookupStrategy"
class="net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl.DefaultIssuerIDLookupFunction"
scope="prototype" />
@@ -124,10 +138,10 @@
</util:list>
<bean id="OIDCAuthnRedirectRequestEncoder"
- class="net.shibboleth.oidc.profile.encoders.impl.HTTPRedirectEncoder" init-method="" scope="prototype"
+ class="net.shibboleth.oidc.profile.encoder.impl.HTTPRedirectAuthnEncoder" init-method="" scope="prototype"
p:httpServletResponse-ref="shibboleth.HttpServletResponse" />
- <bean id="OIDCAuthnPostRequestEncoder" class="net.shibboleth.oidc.profile.encoders.impl.HTTPPostEncoder"
+ <bean id="OIDCAuthnPostRequestEncoder" class="net.shibboleth.oidc.profile.encoder.impl.HTTPPostAuthnEncoder"
init-method="" scope="prototype" p:velocityEngine-ref="shibboleth.VelocityEngine"
p:httpServletResponse-ref="shibboleth.HttpServletResponse" />
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
index c58dde7..1935724 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
@@ -27,10 +27,12 @@
<!-- <evaluate expression="SAMLProtocolAndRole" /> maybe we need an OIDC role selector here, to say this is an
OP over the normal RP -->
- <evaluate expression="OIDCMetadataLookup" />
-
+ <evaluate expression="OIDCProviderMetadataLookup" />
<evaluate expression="InitializeRelyingPartyContext" />
<evaluate expression="SelectRelyingPartyConfiguration" />
+ <!-- Get RP information relating to this OP -->
+ <evaluate expression="OIDCClientMetadataLookup" />
+
<!-- <evaluate expression="PostLookupPopulateAuditContext" /> -->
<evaluate expression="InitializeOutboundMessageContext" />
<evaluate expression="SelectProfileConfiguration" />
diff --git a/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/clientinfo-resolver-system.xml b/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/clientinfo-resolver-system.xml
new file mode 100644
index 0000000..09dfce8
--- /dev/null
+++ b/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/clientinfo-resolver-system.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy"
+ default-lazy-init="true">
+
+ <bean id="shibboleth.oidc.RelyingPartyClientInformationProvider" lazy-init="false"
+ class="net.shibboleth.oidc.metadata.RelyingPartyClientInformationProvider"
+ p:embeddedResolver-ref="shibboleth.oidc.ChainingClientInformationResolver">
+ </bean>
+
+ <bean id="shibboleth.oidc.ChainingClientInformationResolver"
+ class="net.shibboleth.oidc.metadata.impl.ChainingClientInformationResolver"
+ p:id="InternalEmbeddedChainResolver"
+ p:resolvers="#{getObject('shibboleth.oidc.ClientInformationResolvers')}"/>
+
+ <bean id="shibboleth.oidc.FilesystemClientInformationResolver" abstract="true"
+ class="net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl.FilesystemClientInformationResolver"/>
+
+ <!-- Wildcard import hook for plugins. -->
+ <!-- <import resource="classpath*:/META-INF/net/shibboleth/idp/plugin/oidc/op/service/clientinfo/postconfig.xml" /> -->
+
+</beans>
\ No newline at end of file
diff --git a/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/providermetadata-resolver-system.xml b/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/providermetadata-resolver-system.xml
index fe8410a..f5a6720 100644
--- a/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/providermetadata-resolver-system.xml
+++ b/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/providermetadata-resolver-system.xml
@@ -92,6 +92,6 @@
<!-- Wildcard import hook for plugins. -->
<!-- TODO: Not sure we need this -->
- <import resource="classpath*:/META-INF/net/shibboleth/idp/plugin/oidc/op/service/clientinfo/postconfig.xml" />
+ <!-- <import resource="classpath*:/META-INF/net/shibboleth/idp/plugin/oidc/op/service/clientinfo/postconfig.xml" /> -->
</beans>
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationControllerTest.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationControllerTest.java
index 03006ff..676c62c 100644
--- a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationControllerTest.java
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationControllerTest.java
@@ -60,8 +60,8 @@ import net.shibboleth.idp.session.context.SessionContext;
import net.shibboleth.idp.ui.context.RelyingPartyUIContext;
import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration.OIDCHttpRequestMethod;
import net.shibboleth.oidc.profile.core.OIDCAuthenticationRequest;
-import net.shibboleth.oidc.profile.encoders.impl.AbstractOIDCMessageEncoder;
-import net.shibboleth.oidc.profile.encoders.impl.OIDCMessageEncoder;
+import net.shibboleth.oidc.profile.encoder.OIDCMessageEncoder;
+import net.shibboleth.oidc.profile.encoder.impl.AbstractOIDCMessageEncoder;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.net.HttpServletSupport;
diff --git a/idp-oidc-rp-impl/src/test/resources/conf/authn/oidc-clientinfo-resolvers.xml b/idp-oidc-rp-impl/src/test/resources/conf/authn/oidc-clientinfo-resolvers.xml
new file mode 100644
index 0000000..99f54d9
--- /dev/null
+++ b/idp-oidc-rp-impl/src/test/resources/conf/authn/oidc-clientinfo-resolvers.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <util:list id="shibboleth.oidc.ClientInformationResolvers">
+ <ref bean="ExampleFileResolver" />
+ </util:list>
+
+ <bean id="ExampleFileResolver"
+ class="net.shibboleth.idp.plugin.authn.oidc.rp.metadata.impl.FilesystemClientInformationResolver" p:id="ExampleFileResolver1"
+ c:metadata="metadata/oidc-clients.json"/>
+
+</beans>
\ No newline at end of file
diff --git a/idp-oidc-rp-impl/src/test/resources/metadata/oidc-clients.json b/idp-oidc-rp-impl/src/test/resources/metadata/oidc-clients.json
new file mode 100644
index 0000000..0a8e6fa
--- /dev/null
+++ b/idp-oidc-rp-impl/src/test/resources/metadata/oidc-clients.json
@@ -0,0 +1,26 @@
+[
+ {
+ "issuer": "https://op.example.com",
+ "scope": "openid info profile email address phone",
+ "redirect_uris": [
+ "https://192.168.0.150/static"
+ ],
+ "client_id": "demo_rp",
+ "response_types": [
+ "id_token",
+ "id_token token"
+ ]
+ },
+ {
+ "issuer": "https://op2.example.com/",
+ "scope": "openid info profile email address phone",
+ "redirect_uris": [
+ "https://192.168.0.150/static2"
+ ],
+ "client_id": "demo_rp2",
+ "response_types": [
+ "id_token",
+ "id_token token"
+ ]
+ }
+]
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list