OPMetadataClientRegistration

Overview

There are two general ways to register and manage OIDC "clients" (RPs), with metadata and dynamically. Metadata-based registration is analagous to the way CAS and SAML are supported in the IdP, through metadata resolution to files or online sources. It's not necessarily static since there are many ways of obtaining metadata (e.g., the process could be offloaded to some other system entirely but with output compatible with one of the supported formats).

A "native" JSON format is supported, as well as a profile of SAML metadata. The former is obviously more concise, but the latter is advantageous because it supports signing by third parties, and because of the myriad configuration features that rely on the use of SAML metadata, and its extensions, and for consistency with the rest of the supported protocols. There are also more advanced metadata loading options using the SAML format, such as the LocalDynamicMetadataProvider or DynamicHTTPMetadataProvider approaches.

For further information on configuring support for resolving this information, see OPClientResolution.

Avoiding Registration 3.1

As of V3.1, not every feature actually requires registration and management of clients. While the support for this with SAML or CAS is not heavily used, the IdP has always allowed for so-called “unverified” or (in very old versions, “anonymous”) relying party configuration, whereby profiles may be enabled for systems that are not found in metadata. This support is currently not universal within the OP feature set, but is expected to expand going forward because of the fact that OIDC and OAuth typically rely on back-channel communication to the OP with authentication methods that don’t necessarily require metadata.

Because of this additional authentication requirement, it may be desirable to operate (within an enterprise at least) with a more default profile configuration that extends to any clients issued credentials by some general management approach, such as service accounts managed within an IDM solution. Issuing service accounts may be more lightweight for many organizations than capturing details for creation of client metadata.

With V3.1, the following features are meant to operate successfully in the absence of client metadata, provided the relevant profiles are enabled for unverified relying party use:

These profiles all support client authentication, and this can be used in lieu of actually registering metadata for clients if desired.

As of V3.1, this support does not extend to the full OIDC login flow but this is expected to be addressed in a future enhancement.

JSON Format

Each RP is defined with a JSON structure that is defined by the OpenID Connect Dynamic Client Registration 1.0 specification. That is, the format is just the format of the messages in that protocol. The required fields are:

Name

Type

Description

Name

Type

Description

client_id

string

OIDC client identifier for the RP

response_types

array of strings

Accepted client response types

scope

string

Known scopes (space-delimited list in one string)

redirect_uris

array of strings

Required redirect response locations for the RP

Multiple RPs can be configured in a single file, and must be included in a JSON array.

Examples

An example of a JSON file with minimal settings:

1 2 3 4 5 6 { "client_id": "demo_rp", "response_types": ["id_token"] "scope": "openid info profile email address phone", "redirect_uris": ["https://192.168.0.150/static"], }

An example with multiple RPs:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 [ { "client_id": "demo_rp", "response_types": ["id_token"] "scope": "openid info profile email address phone", "redirect_uris": ["https://192.168.0.150/static"], }, { "client_id": "demo_rp2", "response_types": ["id_token"] "scope": "openid info profile email address phone", "redirect_uris": ["https://192.168.0.150/static2"], } ]

SAML/XML Format

The alternative format supported is a profile of SAML metadata described in OAuthRPMetadataProfile. This profile makes heavier use of extensions than past adaptations of SAML metadata because of the comparative complexity of OAuth and OIDC relative to simpler protocols that have more similarity to SAML.

There are also additional considerations around the way keys are resolved. OIDC typically relies on untrusted leap-of-faith access to remote, unsigned JSON files to acquire frequently-rotated client secrets (i.e. shared/symmetric keys, not longer-lived keypairs), and the use of SAML metadata has to account for that difference. The techniques below are all auto-configured into the system.

Public Key Resolution

Public keys can be resolved in two previously supported ways (<ds:KeyValue> or <ds:X509Data> elements) and two "novel" ways specific to OIDC:

You can embed a JSON Web Key Set, encoded into base64, inside a <KeyDescriptor> metadata element. This is just a way of embedding a more "native" structure into the metadata into the metadata in the same way that a certificate would be.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <md:KeyDescriptor> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:KeyName>mockJwkId</ds:KeyName> <oidcmd:JwksData xmlns:oidcmd="urn:mace:shibboleth:metadata:oidc:1.0"> ewogICJrdHkiOiAiUlNBIiwKICAiZSI6ICJBUUFCIiwKICAia2lkIjogIm1vY2siLAogICJhbGci OiAiUlMyNTYiLAogICJuIjogInBKcHRScnpyRlhEUnBaWkdpRmc1eW9KeVRPMlphUENSNEcwbjEx aUVSclBTdlVYX202Qmdvak5qVEZISk1pa19pbGhtVzY0Q3JLdGlMdklRTFF6VWV5RXdDZHdYZVB3 UVpNeEV4VDJPV2thQy1DV0ZJNHR4X2VFWGRkUGtja1NMRERhMEVQd3dzWktQUFhoRTNWNTBfZ3pW VDJZQVRvRE9fMmoyeGpWcHFzU0dFc0xpYjZqLW52dFpVVV9CMHNHeUppR1ZzMkpUTmhCTVNrT2tR Zks2NkNCcW1sbzBuUE5NYVIxbWl2dG5JUG1aNnJKVHcwUDVZZ0dFS1hmZjBsa25Ib25ZVmRsVktw c0Q4VW5hY0JzdFlyeUhsM0NQR2Uyc3RmR2ExZ3N6NEdIVGVfRnlWVk04UlNoQ2dYVVo3MTdoenpf ekdQaVhDQkw0ZktEek5ZUXpIUSIKfQo= </oidcmd:JwksData> </ds:KeyInfo> </md:KeyDescriptor>

The decoded data above is:

1 2 3 4 5 6 7 { "kty": "RSA", "e": "AQAB", "kid": "mock", "alg": "RS256", "n": "pJptRrzrFXDRpZZGiFg5yoJyTO2ZaPCR4G0n11iERrPSvUX_m6BgojNjTFHJMik_ilhmW64CrKtiLvIQLQzUeyEwCdwXePwQZMxExT2OWkaCCWFI4tx_eEXddPkckSLDDa0EPwwsZKPPXhE3V50_gzVT2YAToDO_2j2xjVpqsSGEsLib6jnvtZUU_B0sGyJiGVs2JTNhBMSkOkQfK66CBqmlo0nPNMaR1mivtnIPmZ6rJTw0P5YgGEKXff0lknHonYVdlVKpsD8UnacBstYryHl3CPGe2stfGa1gsz4GHTe_FyVVM8RShCgXUZ717hzz_zGPiXCBL4fKDzNYQzHQ" }

You can reference a JWKS (as in the other JWKS example) remotely via a URI. This is analagous to a rarely used (because of security, obviously) technique of remotely referencing certificates.

1 2 3 4 5 6 <md:KeyDescriptor> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:KeyName>mockJwkId</ds:KeyName> <oidcmd:JwksUri>https://example.org/jwks</oidcmd:JwksUri> </ds:KeyInfo> </md:KeyDescriptor>

Client Secret Resolution

Client secrets, which are effectively either passwords or symmetric keys, are not something natively understood by SAML metadata, so extensions are defined to support them in one of the following ways.

You can embed a client secret directly inside a <KeyDescriptor> metadata element. This works well for closely managed systems such as within an enterprise.

1 2 3 4 5 <md:KeyDescriptor> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <oidcmd:ClientSecret>verySecretClientSecretKeyValue1234567890</oidcmd:ClientSecret> </ds:KeyInfo> </md:KeyDescriptor>

Support also exists for indirectly referencing client secrets and resolving them at runtime separately. The metadata syntax is simply:

1 2 3 4 5 <md:KeyDescriptor> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <oidcmd:ClientSecretKeyReference>secretReference1</oidcmd:ClientSecretKeyReference> </ds:KeyInfo> </md:KeyDescriptor>

The reference string is just a label that has to correspond to some external source.

Actually resolving secrets by reference requires one or more resolution beans be supplied in a list named shibboleth.oidc.ClientSecretValueResolvers, which does not exist by default.

There are two built-in types of resolvers.

Property-Based Resolution

Client secrets can be placed in a Java properties file (the keys are the labels used in the metadata reference and the values are the secrets). You can supply any number of such sources in the resolver list, generally in conf/global.xml. Each source is defined using a parent bean named shibboleth.oidc.PropertiesClientSecretValueResolver:

1 2 3 4 <util:list id="shibboleth.oidc.ClientSecretValueResolvers"> <bean parent="shibboleth.oidc.PropertiesClientSecretValueResolver" p:resource="%{idp.home}/credentials/client-secrets.properties" /> </util:list>

Attribute Resolver Resolution

A "generic" solution to resolving secrets is provided by means of leveraging the AttributeResolver to resolve the secret. The parent bean named shibboleth.oidc.ResolverServiceClientSecretValueResolver along with a set of attribute IDs will invoke the resolver and attempt to find a string value amongst them to return. During the resolution process, the "principal" variable is populated with the client secret reference label.

1 2 3 4 <util:list id="shibboleth.oidc.ClientSecretValueResolvers"> <bean parent="shibboleth.oidc.ResolverServiceClientSecretValueResolver" p:attributeIds="ClientSecretAttribute" /> </util:list>

To simplify the configuration of the resolver, you may conditionalize connectors by attaching a resolutionPhases attribute set to "ResolverServiceClientSecretValueResolver", causing them to run only during this special case. You can also set excludeResolutionPhases to invert the check for other connectors.

Hashed Secrets 3.1

If a secret value is prefixed by “{SHA2}”, then the supplied secret is hashed (with SHA-256) and base64-encoded before comparing it to the rest of the secret string. This is an unsalted hash so is not really suitable for exposing to offline attacks but is at least obsfuscated.

Reference

Beans

Name / Type

Description

Name / Type

Description

shibboleth.oidc.ClientSecretValueResolvers

List<net.shibboleth.oidc.metadata.ClientSecretValueResolver>

List of client secret resolvers to apply to any <oidcmd:ClientSecretKeyReference> elements in SAML metadata

shibboleth.oidc.PropertiesClientSecretValueResolver

net.shibboleth.oidc.metadata.impl.PropertiesClientSecretValueResolver

A resolver that looks for secrets in a Java properties file set via the resource bean property

shibboleth.oidc.ResolverServiceClientSecretValueResolver

net.shibboleth.oidc.metadata.impl.ResolverServiceClientSecretValueResolver

A resolver that executes the AttributeResolver to resolve one or more client secrets via attributes set via the attributeIds bean property