OPDynamicClientRegistration
File(s): conf/relying-party.xml, conf/oidc.properties
Format: Native Spring, Spring Properties
Overview
There are two general ways to register and manage OIDC "clients" (RPs), using out of band metadata and dynamically. Dynamic registration is described by the OpenID Connect Dynamic Client Registration 1.0 specification. Support for this profile is located at /idp/profile/oidc/register
.
Activation and Use
Support for dynamic registration is enabled by enabling a profile configuration bean called (or inherited from) "OIDC.Registration". Prior to V3.1, the only way to enable this profile is via the shibboleth.UnverifiedRelyingParty bean (see RelyingPartyConfiguration) since the RP by definition isn't verified at the time of initial registration.
<bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
<property name="profileConfigurations">
<list>
<bean parent="OIDC.Keyset" />
<bean parent="OIDC.Registration" />
</list>
</property>
</bean>
With V3.1, the endpoint is now an OAuth-protected resource. When configured for unverified use, no token is required; otherwise clients must present an access token to use the endpoint and their registration request can be influenced by metadata policy attached to the profile configuration and/or in the access token itself.
Issuing Registration Access Tokens
To generate an access token accepted by this endpoint (something not defined by any standards), an administrative flow implementing a simple REST service exists at /idp/profile/admin/oidc/issue-registration-access-token
. A command line script to make simple requests to this endpoint is also installed to bin. This endpoint can be tailored to address two different scenarios:
OP operators generating tokens on behalf of clients (very loose control over populating tokens)
Client developers/operators authenticating to the endpoint to request their own tokens (generally much more access control required)
To address these two “extreme” ends of the spectrum, the operation of the endpoint is configurable (as all administrative features can be) to support user authentication, resolve attributes, and apply the resulting request context to a number of different access control policy beans used to control whether to honor a particular request.
The REST endpoint supports the following parameters. All are optional, but at least one of policyId or policyLocation MUST be supplied.
Name | Description |
---|---|
lifetime | Token lifetime (expressed as an ISO Duration, e.g., PT2H), bounded by a maximum/default set by idp.oidc.admin.registration.defaultTokenLifetime property |
policyLocation | Locates an on-server resource containing a metadata policy to embed in the token to be enforced on use. This is generally used by an OP operator to identify pre-defined policy documents on the server. This is how policy is added to the token by value. |
policyId | Identifies a metadata policy by means of an identifier that maps back to a matching RelyingParty override. The match is based on the |
clientId | Optionally specifies the OAuth/OIDC client_id to register with. When absent, registering with the token will (as in the absence of a token) randomly generate an opaque and largely unwieldy client_id that isn’t meant to be used in OP policy. Specifying the client_id ahead of time allows registrations to be “reserved” for named clients that get “filled in” by clients when ready to proceed. |
replacement | Used only if “clientId” is also supplied. If “true”, the token can be used to register a client’s metadata multiple times within the life of the token, allowing update/replacement of client metadata as needed. |
To control endpoint use, there are 4 independent access control policies applied to allow a token to be issued (these are the traditional IdP access policies, not the metadata policies referred to above). One is a front-door policy applying to any request, and three are specific to use of the “policyLocation”, “policyId”, and “clientId” parameters (the policies are applied only if the parameter exists). Properties (see below) are typically used to define which named policies to use.
Storage
The dynamic client registration implementation relies on a StorageService for storing the dynamically registered client information. The in-memory and JPA options have been tested. Expired client information is automatically pruned.
Obviously the simple in-memory service is only sufficient for testing, and the only real option designed for durable persistence is the JPA variant using a database.
The desired storage service bean can be set with the idp.oidc.dynreg.StorageService property in conf/oidc.properties. Also note that the deployer must configure a StorageServiceClientInformationResolver exploiting that same service to allow the information to be accessed when requests are handled.
There is also a hook in V3.1+ for completely substituting a different management implementation by defining idp.oidc.dynreg.clientInformationManager to the name of such a bean, though this would also entail other customizations, such as to the resolution process.
Managing Registrations
V3.1 adds an additional administrative flow that can be used by operations staff to query and delete registrations. A command line script is provided for basic use, but the REST endpoint lives at /idp/profile/admin/oidc/clients
and requires a single query string parameter, client_id
. The HTTP method can be changed to DELETE to perform a removal operation, while the default (GET) will query the service for existing client metadata.
Note that this flow is strictly usable for access to OIDC “native” client metadata, not SAML metadata.
Profile Settings
Virtually all the configuration options below can be set via two different properties: a static property that explicitly sets the value to use and a lookup strategy or predicate property that takes a Function or Predicate and returns the value to use. The dynamic property is generally named "propertyNamePredicate" or "propertyNameLookupStrategy" for Boolean- and non-Boolean-valued properties respectively.
Most of these options are constraints on the values that can be registered, rather than actually controlling the behavior of the registration profile itself.
Supported Client Metadata
The following standard client metadata fields are currently supported:
Field | Req? | Default | Notes |
---|---|---|---|
redirect_uris | Y |
|
|
response_types |
| "code" | Defaults to "code" |
grant_types |
|
| One of "authorization_code", "implicit", and "refresh_token" |
application_type |
|
|
|
contacts |
|
|
|
subject_type |
|
| Default can be set by idp.oidc.dynreg.defaultSubjectType property |
jwks / jwks_uri |
|
|
|
token_endpoint_auth_method |
|
|
|
logo_uri |
|
|
|
policy_uri |
|
|
|
tos_uri |
|
|
|
In addition to the standard fields, the following is supported:
scope
If present, all the requested scopes are added to the stored client metadata. If not present, then the default scope set is stored. The default scope (space-separated list of values, e.g. "openid info") can be configured with the idp.oidc.dynreg.defaultScope property.
All the other (standard or not) fields in the request message are currently ignored. The response message contains all the fields that were stored by the OP during the registration process.