R. Hedberg, Ed. | |
independent | |
R. Gulliksson | |
UmU | |
M. Jones | |
Microsoft | |
J. Bradley | |
Ping Identity | |
September 9, 2016 |
OpenID Connect Federation 1.0 - draft 01
openid-connect-federation-1_0
The OpenID Connect standard specifies how a Relying Party (RP) can discover metadata about an OpenID Provider (OP), and then register to obtain client credentials. During discovery and registration there is no automated mechanism for the OP or the RP to verify the information exchanged during this process. All the information is self-asserted.
In an identity federation context this is not sufficient. The participants of the federation must be able to trust information provided about other participants in the federation.
This document describes how an identity federation can be built around a trusted third party, the federation operator.
The OpenID Connect specification defines how a Relying Party and an OpenID Connect Provider can exchange information dynamically about each other. This information is necessary for future successful OIDC communication.
One problem with using dynamic discovery and registration is that the correctness of the information that is exchanged can not be easily verified by the recipient since it is self-asserted.
Another problem that has been raised is the dependency on TLS as the sole protection against attacks on the transferred information. These last couple of years a number of problems with OpenSSL, which is probably the most widely used TLS library, has been discovered that puts reasonable doubt into this dependency.
This document extends Signed Metadata, as introduced by OAuth 2.0 Authorization Server Metadata [I-D.draft-ietf-oauth-discovery], to create so called metadata statements. Metadata statements together with the use of a trusted third party (that verifies and enforces some common policy), can be used to transfer verified data and trust in the data between clients and servers.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119].
A metadata statement asserts metadata values about an entity (client or server).
These extra metadata parameters appear in both provider and client metadata statements:
Metadata statements and signing keys can be transferred in two different ways: either by including the information in the statement, or by providing a URI that points to the information. How metadata statements and signing keys are transferred is independent of each other. It is NOT allowed to divide the information (metadata statements or signing keys) into two pieces and send one in the statement and leave the rest to be fetched using the URI.
Along the same line if both jwks_uri and signed_jwks_uri are present, which they might be for backward compatibility reasons, then signed_jwks_uri SHOULD be preferred.
All parameters defined in section 2 of OpenID Connect Dynamic Client Registration 1.0 [OpenID.Registration] are allowed in a metadata statement.
To that list is added:
All parameters defined in section 3 of OpenID Connect Discovery 1.0 [OpenID.Discovery]
The metadata for each entity in the federation is described by one or more metadata statements (for example, MS0, MS1, ..., MSn). MS0 is the most generic, and MS1-MSn would in turn be successively more specific. To describe an entity belonging to an organization, MS0 would typically contain information that belongs to the organization, for example tos_uri, contacts and the like while MSn would contain information about the specific entity like authorization_endpoint for an OP or redirect_uris for a RP.
The metadata for a specific entity is constructed by starting with the information in MS0 and then adding the information in MS1 to MSn using the rule below.
If the same claims appear in MSa and MSb (b > a, a=0,..,n, b=0,..,n) then unless the value in MSb is less or equal to the value in MSa then the value in MSb should be ignored.
The reason for us to define a compounded metadata statement in this way is so new OIDC entities can be created and described without having to involve all the parties up to and including the FO. Only the party responsible for the entity and the immediate superior party, who has to sign the new information, has to be involved.
The following is a non-normative example of a set of client-specific metadata statements who together form the metadata for an entity:
MS0
{ "contacts": ["dev_admin@example.com", "ops_admin@example.com"], "logo_uri": "https://example.com/logo.jpg", "policy_uri": "https://example.com/policy.html", "tos_uri": "https://example.com/tos.html" }
MS1
{ "scope": "openid eduperson", "response_types": ["code"], }
MS2
{ "contacts": ["dev_admin@example.com"], "redirect_uris": ["https://example.com/rp1"], }
sum(MS0...2)
{ "contacts": ["dev_admin@example.com"], "logo_uri": "https://example.com/logo.jpg", "policy_uri": "https://example.com/policy.html", "tos_uri": "https://example.com/tos.html" "scope": "openid eduperson", "response_types": ["code"], "redirect_uris": ["https://example.com/rp1"], }
A set of metadata statements, together describe an entity are brought together using the metadata_statement parameter.
The following is a non-normative example of a compounded metadata statement. Also note that the the metadata_statement MUST be a signed JWT. In this example, the only the parts of the signed JWT payload pertinent to the example are shown.
{ "redirect_uris": ["https://example.com/rp1"], "metadata_statements": [ { "scope": "openid eduperson", "response_types": ["code"], "metadata_statements" : [ { "contacts": ["dev_admin@example.com"], "logo_uri": "https://example.com/logo.jpg", "policy_uri": "https://example.com/policy.html", "tos_uri": "https://example.com/tos.html" } ] } ] }
The trust model is based on linking together signing keys, referred to in the metadata statements and represented asJWK Sets [RFC7517]. Each signature chain is rooted in the trusted third party's signing keys. By verifying such signature chains, the entities can establish trust in the metadata.
The Federation Operator (FO) is the trusted third party. The FO MUST have a globally unique identifier. It will publish a JWKS, containing the signing keys that the FO will use for signing metadata submitted to it, at a HTTPS URL which server certificate MUST appear in a well-known Certificate Transparency log [RFC6962]. The key IDs of the FO's signing keys MUST be globally unique since they are the keys in the metadata_statment_uris object.
For the following description, this is assumed to be true: A federation consists of a number of members, and each member has one or more representatives registered with the federation. These representatives are allowed to issue metadata signing requests on behalf of the member to the federation. Below such a representative is called a Level 0 Requester (L0Req). Within each member unless all entities belonging to the member is handled by the L0Req there may exists parties that are responsible for single or groups of entities. Within these parties we may have further subdivisions such that we end up with Level 0, 1, 2, 3 or more requesters. This document makes no assumption on the number of levels.
Note that the level N requester is the level N+1 signer.
The innermost metadata statement in the nest of metadata statements is the one that the FO has signed. That statement MUST NOT contain any references to other metadata statements. All other metadata statements in the nest MUST contain at least one reference to another metadata statement.
These are the steps that are performed to construct a signed metadata statement. A metadata signing request may be about one specific entity or a group of similar entities.
An example of the construction of a compounded metadata statement.
def verify(ms, sign_keys): keys = [] pl = get_payload(ms) if 'metadata_statements' in pl: md = [] for statement in pl['metadata_statements']: _ms, _md = verify(statement, sign_keys) if _ms: keys.append(get_keys(_ms)) if _md: md.extend([_ms, _md]) else: md.append(_ms) elif 'metadata_statement_uris' in pl: md = [] for _iss, uri in pl['metadata_statement_uris'].items(): statement = html_get(uri) _ms, _md = verify(statement, sign_keys) if _ms: keys.append(get_keys(_ms)) if _md: md.extend([_ms, _md]) else: md.append(_ms) else: return verify_signature(ms, pl['iss'], sign_keys), [] return verify_signature(ms, pl['iss'], keys), md
Verifying the received metadata statement involves running a function similar to this:
As can be see from the pseudo code the process is that you successively unpack the metadata statements (this involves base64 decoding the JWS payload without verifying the signature) until you reach the inner most MS (MS0). After having verified the signature of MS0 using the FOs signing keys, you can now use the signing keys included in or referenced from MS0 to verify the signature of the next layer (MS1) and so on.
The trust between the entities is established using the above described extensions in the first two steps of the communication between an RP and an OP. How the RP found the OP in the first place is out of scope for this document.
------ ------ | | <--- 1) Discovery --------> | | | RP | <--- 2) Registration -----> | OP | | | | | ------ ------
After the discovery and registration is completed a first time, those steps SHOULD only be repeated if any changes occur (see notes in respective sections below).
The OP MUST publish its provider metadata as specified by OpenID Connect Discovery 1.0 [OpenID.Discovery]. The RP makes a standard OpenID Provider Configuration Request. The OP responds with its provider configuration and the additional metadata parameters specified in Section 3
The OP MUST support dynamic client registration as described in OpenID Connect Dynamic Client Registration 1.0 [OpenID.Registration]. The RP makes a Client Registration Request including the additional metadata specified in Section 3
This draft allows any entity to belong to more then one federation. During the provider discovery and client registration process the parties has to agree on which federation to use.
An organization may be a member of more the one federation. The RPs it is responsible for may be members of one or more of these.
The organization registers and gets metadata staements signed by each federation. One extreme is that it will mint a new key pair for each federation, the other is that it will use the same key pair for all federations. It does not matter which it chooses, but the end result MUST be that there is one signed RP registration request per signing key. This is then published using metadata_statement_uris or metadata_statements the client registration request.
The following is a non-normative example of an absolutely minimal client registration request sent to an OP:
{ "redirect_uris": ["https://example.com/rp2/callback"], "metadata_statement_uris": { https://swamid.sunet.se/": "https://dev.example.com/rp1/idfed/swamid.jws", "https://www.incommon.org": "https://dev.example.com/rp1/idfed/incommon.jws" } }
As described above, when the OP receives a request like this it will choose which federation it will work within and then signal that by only returning that corresponding information in the metadata_statements / metadata_statement_uris in the registration response.
The following is a non-normative example of an OPs response on the client registration request above:
{ "client_id": "abcdefgh", "client_secret": "0123456789", "client_id_issued_at": 1462375583, "client_secret_expires_at": 1462379183, "redirect_uris": ["https://example.com/rp2/callback"], "metadata_statement_uris": { "https://swamid.sunet.se/": "https://dev.example.com/rp1/idfed/swamid.jws", } }
An OP has the choice of whether it wants one key pair per federation, one key pair for everyone, or anything in between. And, like the RP owner, it has to produce one signed metadata statement per key used.
The following is a non-normative example of an OPs response to a provider configuration request:
{ "issuer": "https://foo.example.org/op/fDTowvP0slEdEAcc", "response_types_supported": ["code", "code id_token", "token"], "grant_types_supported": ["authorization_code", "implicit", "urn:ietf:params:oauth:grant-type:jwt-bearer"], "subject_types_supported": ["pairwise", "public"], "id_token_signing_alg_values_supported": ["RS256"], "metadata_statement_uris": { "https://swamid.sunet.se/": "https://foo.example.org/op/idfed/swamid.jws", "https://www.incommon.org": "https://foo.example.org/op/idfed/incommon.jws" "https://www.switch.ch": "https://foo.example.org/op/idfed/switch.jws" "https://www.aco.net/": "https://foo.example.org/op/idfed/aconet.jws" }
There are a number of timeouts that MUST considered
Taking this into consideration, an OP MUST NOT assign a lifetime to a client registration that exceeds the lifetime of the metadata statement signatures.
TBD
TBD
[I-D.draft-ietf-oauth-discovery] | Sakimura, N., Bradley, J. and M. Jones, "OAuth 2.0 Authorization Server Metadata", August 2016. |
[OpenID.Discovery] | Sakimura, N., Bradley, J., Jones, M. and E. Jay, "OpenID Connect Discovery 1.0", August 2015. |
[OpenID.Registration] | Sakimura, N., Bradley, J. and M. Jones, "OpenID Connect Dynamic Client Registration 1.0", August 2015. |
[RFC2119] | Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997. |
[RFC6749] | Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, October 2012. |
[RFC6962] | Laurie, B., Langley, A. and E. Kasper, "Certificate Transparency", RFC 6962, DOI 10.17487/RFC6962, June 2013. |
[RFC7515] | Jones, M., Bradley, J. and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 2015. |
[RFC7517] | Jones, M., "JSON Web Key (JWK)", RFC 7517, DOI 10.17487/RFC7517, May 2015. |
The necessary steps for adding a Relying Party to a federation
The following JWKS represents the signing key that the Federation Operator is using in the following example:
{ "keys": [ { "d": "DpFZnXz8fcKmOxFPfPdh3aZz44U2ZWm1Mxy6CiqHYcA80KVAY-wrjKFV4e iSl9JENpoWXax4dpMcyJa2TdAXL9-4WqGNQAPRvdOfHcJM_uaBSGZwsuqAqZi_0sbNxurG gbjKV38ra-iz42fcSXHCgNdMJjCi3VixS8iASHGU82R6mYyVeMWdX_j2RG--41PDxud4xS YCKDuR6s2qlLVXyCZqFu_Yzl5zChiNxZJ_ggcxyL6i_hngi1oSbbVjgNKTcJNaIdOfzzcn Ud5J9GP941-tylwg7NC3gRo1bXlUx6HFx3LkYe1PdroHhQd92RPyJdPqHDfbizJ4sjXN4c Nq-Q", "e": "AQAB", "kid": "uZX0-P1-TMsZRqK1SeXpdLgsLoeUNskN2W_rwBNKAtc", "kty": "RSA", "n": "rqJ_CFECPF2nBD1eXkFonJo5gGcbnCvDudm_-7f1thcQqiuY2Xz0eKqQ2H P3Nw-wP5q2hKbNVgAQSBbMp_AgNwRFmboJKF4cFEr3ZtmvO94bM6L15vUR2HNyX-4LaZ6S 9u35jSikOVJDt1BK-72w_DKeb8O8qa2dl9k7F6QZJQT6Nfh5rEALQLOZgwBgZAUpu2tQUh 3TFpwe3J_rQtCBbI3r0W1XoM1pD3EXTm9MI_aANRL82rh7_ZqLwGeBprD3F6ns9i5-psQ0 UZ-2eVjN6J1um40U6ysu3QjFUZEwb0yxNVx2D9bzOPMHwo6GAzePhJ46rI8NQ0NwJdB7lN vrhw", "p": "y4VcmM4QZoIjsGlTE7jvkJzYAud9Hz3uexVdeTShHnS-btLySSP70EWdvI CkHK7Z4KikNZaD3cET978LmkoG03WZcs7iEEg7hQ0N7ePMv7P1w6X1Z2_IeWml0c4iFSMa GPJk8a65HgBZ8fYPXFtERI7e1M--oqCrsTFikP8wYQU", "q": "26pTV-JNgwx3LMrqEKIoIvHwLKfjFouRZXtTnOJP9G9BZ9vhAn1qX06M-x W02G3qGzhQEpNZKMj54APNcqkg4PH1wMJmJ-cs1T44KoNhhihoHd6awT7PGNMo9I728CwY fkM3ZW-BsgGBzQcfdI043cV3ebXzIEWwPbqTR44p8Bs", "use": "sig" } ] }
{ "keys": [ { "d": "RJmqe2KiVOShoTMaZBmoMLkmeZY97PW3TOgSGDgZejL6I2qdhNlBAa3e9N z6ggkWpxEy6IGNGetwNwS9aYA_Z6m45kaaUHXGKol_R_5s4TJryXUppxWDuHScE_dVcfzl usm9Cq8J-U-xoaoKL36I3rakCJ_dWpsGNDpYSMenXcXuX-gJ5-HvSTETV5Bp23izUF4BH8 TSVWniD8Vk5Hv8EtWVqsqc7YmIG1zW_ctJhK7peymmNIVpcGpIxaT8agUOS-hcNxpN4AlY rELn2twzq8tXp5bPZNiHHNXgzXANy5BgNFXXnZFqFiNiBn3agQxF2aiu4Ei5k5OidHTV8q eGWQ", "e": "AQAB", "kid": "z414hVxt2-nkbqgG3VFYOZGB3Miwuhe75SfWT1BQQTc", "kty": "RSA", "n": "waDXGJwu9pV3gMY7rtpq3OYSAG1HZy7qilGC3ULMxJxjhSQCJ7M9PBC4uo F_f5178FebpKBIoT3_YzqETt9Ry_6NA_mGBq6xtjEgnmNv6ktQj8hKI0tYheWRHMJIt2ay 8IwnV-3LD0Q_Nn7E3YgGaJUBlzDgJxQQcRVGFEOcFL-7TiKtVdPmPDGcSF7FivaGJO-MVq mDkCsZVMTZoqmKeuaqbshsDjxy9GaiImQLe8tyzkhxEoG7qvovlGoV4AE8WroMinx0qWvg lR8n041qQhrUMtoQMDCI53uLy6ZSR0jbNNEwvDBbiqD4Hm3piAwTUrGKWYLxbeicK_7A6g F2Sw", "p": "3SBEMBmIGztaOpCH-C9vwr80SyXm6M1uwCoKjBOiy_-kJ03jvacztd5CEO cCvhRLVvl3rEYSP97DR_Eju-jlKWi92tbIECGvWzgszMHLdEdjvVvpJLlOSAfFMYsaPxa1 Sw2HS7RgoAwIxD5HVcdPK-3cJ5Gi0hInbz-ufrH4ru0", "q": "4CphaFI0lSGr0HNifXJBN5JkXmCZp6WX06cI4pR_DwZAHTojc8dK1ECMHU 2oP2nPn1pmAVZj4p98vO0MfTxSgNB15EmDRkic_cmS-SenUUf7Pl3avJwpZq_qxYPqDajA gWHuuci-2zKXRlKS_ZCz1MAmx-gV0We3AnletWV52xc", "use": "sig" } ] }
Developer creates its signing key pair.
The developer submits registration data to Federation Operator (FO).
{ "contacts": [ "dev_admin@example.com" ], "logo_uri": "https://example.com/logo.jpg", "policy_uri": "https://example.com/policy.html", "signing_key": { "e": "AQAB", "kid": "z414hVxt2-nkbqgG3VFYOZGB3Miwuhe75SfWT1BQQTc", "kty": "RSA", "n": "waDXGJwu9pV3gMY7rtpq3OYSAG1HZy7qilGC3ULMxJxjhSQCJ7M9PBC4uoF_ f5178FebpKBIoT3_YzqETt9Ry_6NA_mGBq6xtjEgnmNv6ktQj8hKI0tYheWRHMJIt2ay8I wnV-3LD0Q_Nn7E3YgGaJUBlzDgJxQQcRVGFEOcFL-7TiKtVdPmPDGcSF7FivaGJO-MVqmD kCsZVMTZoqmKeuaqbshsDjxy9GaiImQLe8tyzkhxEoG7qvovlGoV4AE8WroMinx0qWvglR 8n041qQhrUMtoQMDCI53uLy6ZSR0jbNNEwvDBbiqD4Hm3piAwTUrGKWYLxbeicK_7A6gF2 Sw", "use": "sig" }, "tos_uri": "https://example.com/tos.html" }
The FO returns a signed metadata statement containing the submitted registration data, and any applied policy restrictions like response_types, signing/encryption algorithms to be used and additional specific policy parameters like the ones specified above.
This is an example of a metadata statement constructed by the FO before it is signed by the FO:
{ "contacts": [ "dev_admin@example.com" ], "exp": 1462438820, "iat": 1462438820, "iss": "https://swamid.sunet.se/", "jti": "e920396fc2cb4ac0aaeb229674fd286a", "kid": "uZX0-P1-TMsZRqK1SeXpdLgsLoeUNskN2W_rwBNKAtc", "logo_uri": "https://example.com/logo.jpg", "policy_uri": "https://example.com/policy.html", "response_types": [ "code", "code id_token", "token" ], "scopes": [ "openid", "email", "phone" ], "signing_key": { "e": "AQAB", "kid": "z414hVxt2-nkbqgG3VFYOZGB3Miwuhe75SfWT1BQQTc", "kty": "RSA", "n": "waDXGJwu9pV3gMY7rtpq3OYSAG1HZy7qilGC3ULMxJxjhSQCJ7M9PBC4uoF_ f5178FebpKBIoT3_YzqETt9Ry_6NA_mGBq6xtjEgnmNv6ktQj8hKI0tYheWRHMJIt2ay8I wnV-3LD0Q_Nn7E3YgGaJUBlzDgJxQQcRVGFEOcFL-7TiKtVdPmPDGcSF7FivaGJO-MVqmD kCsZVMTZoqmKeuaqbshsDjxy9GaiImQLe8tyzkhxEoG7qvovlGoV4AE8WroMinx0qWvglR 8n041qQhrUMtoQMDCI53uLy6ZSR0jbNNEwvDBbiqD4Hm3piAwTUrGKWYLxbeicK_7A6gF2 Sw", "use": "sig" }, "token_endpoint_auth_method": "private_key_jwt", "tos_uri": "https://example.com/tos.html" }
The signed version of this metadata statement, or a link to it, is then expected to be included in the RPs client registration request before being signed by the level 0 signing key.
{ "keys": [ { "d": "BA0bo5OR3ht2KGDeAUpZsKv-Jjo9IKpYA2x7yQhcIH3bt9T2495pXVAHLQ XXnZpjMenz7WPx94ajxIh96Bt59AYx4AwAEaBnPzK8vXLIP-A92NP3HV7vk0p8KWsrEdDw xBaypqRXxz7V5vPGQVnOGg2eKSlP5F4-HoGpU6xDRo8Lptcs5VNx0a9kKVqEu-YpQkc2z2 uLRjl8urOu471sks38U03wRwWDElepUI28jEjhPydVSQw-E5w3yKhHTZeh1mVdNMp7_8LD zScP1Ah5VCRLFfrmx1bOXxXZWHpMD6vgghmaCQGmyhgEr3XNzHVlH4bfVI_2Vrxp6cxHpe 3iYw", "e": "AQAB", "kid": "Tvd2gF4mcNtiYx6FyOOH83Xj_MkF-8yn_rD2Gm06RxY", "kty": "RSA", "n": "2kCKMUluhKV2INV3dS89WQ305J6JL8OJQ1cPk3GQ20Zvraa3DCntNns1xy 9gynGYUQzom7LYAqcmpu7xFGNXH0gN8JyXcCiWl02IuD6lwS6N2d7y6xJm8-mUBiwVrAlh wWL1Bf8JRycRUQ51c6Y8yYrUf2pjeIFQBQEfUhcjNg13L1OUDoWJizy5QhaTe4p2uezYhK lKtSHC7T6Brs6kWJA57j8BY5Tx4p6cyWRGsN58XXfmWg1hA1LjVIwgtSBvax7KRGUY6TXO d5Km2MvJgBOfqAYfh1z0wZRiBdUa0RzsXavf4HGjnwPknYcSY1MwKZCzz_W0_uAiGlHFlN wLSQ", "p": "5279rRhB4IBf5chMgrTVwsAEKWyEsRrIVs5xLFVA5rpOKLN6qGhLO6PU9j msD7dYEa0IA-eTxVCCuMp09KEfyrRAn0OWpWdndu8IR_n2e4zZxBXbf4WuIeZwxfM5PqKi 5LOnp442CthmzbsVD2OLmlgSViWSAP9SLFOBGfniTqs", "q": "8WtasUyu9D9StGJkgolHjofbMnxXzRqpnA-QSV71htsQD3wof-vda8e8Jk DLPPfAYuVYieCHeJYGsT9EHAG1Nyyr9OMzFeo73N1FdKGIGihWHSuvW6sRr6FTta12ZMN7 Jkm3l2rQoZALgvMtdYdDGJ-D3gwusW5nNS3-xJqMPds", "use": "sig" } ] }
The RP gets a signing key
{ "application_type": "web", "jwks_uri_signed": "https://example.com/rp1/jwks.jws", "redirect_uris": [ "https://example.com/rp1/callback" ], "response_types": [ "code" ], "signing_key": { "e": "AQAB", "kid": "Tvd2gF4mcNtiYx6FyOOH83Xj_MkF-8yn_rD2Gm06RxY", "kty": "RSA", "n": "2kCKMUluhKV2INV3dS89WQ305J6JL8OJQ1cPk3GQ20Zvraa3DCntNns1xy9g ynGYUQzom7LYAqcmpu7xFGNXH0gN8JyXcCiWl02IuD6lwS6N2d7y6xJm8-mUBiwVrAlhwW L1Bf8JRycRUQ51c6Y8yYrUf2pjeIFQBQEfUhcjNg13L1OUDoWJizy5QhaTe4p2uezYhKlK tSHC7T6Brs6kWJA57j8BY5Tx4p6cyWRGsN58XXfmWg1hA1LjVIwgtSBvax7KRGUY6TXOd5 Km2MvJgBOfqAYfh1z0wZRiBdUa0RzsXavf4HGjnwPknYcSY1MwKZCzz_W0_uAiGlHFlNwL SQ", "use": "sig" } }
The RP produces a client registration request
{ "application_type": "web", "jwks_uri_signed": "https://example.com/rp1/jwks.jws", "redirect_uris": [ "https://example.com/rp1/callback" ], "response_types": [ "code" ], "signing_key": { "e": "AQAB", "kid": "Tvd2gF4mcNtiYx6FyOOH83Xj_MkF-8yn_rD2Gm06RxY", "kty": "RSA", "n": "2kCKMUluhKV2INV3dS89WQ305J6JL8OJQ1cPk3GQ20Zvraa3DCntNns1xy9g ynGYUQzom7LYAqcmpu7xFGNXH0gN8JyXcCiWl02IuD6lwS6N2d7y6xJm8-mUBiwVrAlhwW L1Bf8JRycRUQ51c6Y8yYrUf2pjeIFQBQEfUhcjNg13L1OUDoWJizy5QhaTe4p2uezYhKlK tSHC7T6Brs6kWJA57j8BY5Tx4p6cyWRGsN58XXfmWg1hA1LjVIwgtSBvax7KRGUY6TXOd5 Km2MvJgBOfqAYfh1z0wZRiBdUa0RzsXavf4HGjnwPknYcSY1MwKZCzz_W0_uAiGlHFlNwL SQ", "use": "sig" }, "metadata_statements": [ "eyJraWQiOiJ1WlgwLVAxLVRNc1pScUsxU2VYcGRMZ3NMb2VVTnNrTjJXX3J3Qk5LQ XRjIiwiYWxnIjoiUlMyNTYifQ.eyJwb2xpY3lfdXJpIjogImh0dHBzOi8vZXhhbXBsZS5j b20vcG9saWN5Lmh0bWwiLCAidG9rZW5fZW5kcG9pbnRfYXV0aF9tZXRob2QiOiAicHJpdm F0ZV9rZXlfand0IiwgImNvbnRhY3RzIjogWyJkZXZfYWRtaW5AZXhhbXBsZS5jb20iXSwg ImxvZ29fdXJpIjogImh0dHBzOi8vZXhhbXBsZS5jb20vbG9nby5qcGciLCAic2NvcGVzIj ogWyJvcGVuaWQiLCAiZW1haWwiLCAicGhvbmUiXSwgImlhdCI6IDE0NjI0Mzg4MjAsICJp c3MiOiAiaHR0cHM6Ly9zd2FtaWQuc3VuZXQuc2UvIiwgImtpZCI6ICJ1WlgwLVAxLVRNc1 pScUsxU2VYcGRMZ3NMb2VVTnNrTjJXX3J3Qk5LQXRjIiwgImp0aSI6ICJlOTIwMzk2ZmMy Y2I0YWMwYWFlYjIyOTY3NGZkMjg2YSIsICJyZXNwb25zZV90eXBlcyI6IFsiY29kZSIsIC Jjb2RlIGlkX3Rva2VuIiwgInRva2VuIl0sICJzaWduaW5nX2tleSI6IHsiZSI6ICJBUUFC IiwgImtpZCI6ICJ6NDE0aFZ4dDItbmticWdHM1ZGWU9aR0IzTWl3dWhlNzVTZldUMUJRUV RjIiwgImt0eSI6ICJSU0EiLCAidXNlIjogInNpZyIsICJuIjogIndhRFhHSnd1OXBWM2dN WTdydHBxM09ZU0FHMUhaeTdxaWxHQzNVTE14SnhqaFNRQ0o3TTlQQkM0dW9GX2Y1MTc4Rm VicEtCSW9UM19ZenFFVHQ5UnlfNk5BX21HQnE2eHRqRWdubU52Nmt0UWo4aEtJMHRZaGVX UkhNSkl0MmF5OEl3blYtM0xEMFFfTm43RTNZZ0dhSlVCbHpEZ0p4UVFjUlZHRkVPY0ZMLT dUaUt0VmRQbVBER2NTRjdGaXZhR0pPLU1WcW1Ea0NzWlZNVFpvcW1LZXVhcWJzaHNEanh5 OUdhaUltUUxlOHR5emtoeEVvRzdxdm92bEdvVjRBRThXcm9NaW54MHFXdmdsUjhuMDQxcV FoclVNdG9RTURDSTUzdUx5NlpTUjBqYk5ORXd2REJiaXFENEhtM3BpQXdUVXJHS1dZTHhi ZWljS183QTZnRjJTdyJ9LCAidG9zX3VyaSI6ICJodHRwczovL2V4YW1wbGUuY29tL3Rvcy 5odG1sIiwgImV4cCI6IDE0NjI0Mzg4MjB9.ZVnHkrdGqQTP36UXwZhb9hhcIc1hgkYNd8d GsyS-uHojrr4lYqkAyDjCr39fJnGvRnJvm_-LQDBfaKFHyGjSCi97uQAN72lWC-FRs-wuE D0abhgSEyrpDBSG0enNvIyOP_BEbo5xx950MJrlcmOT9s2MCI2KPKV4Rt8ZIJUdLO5kWPl fzaHkRZenCnob7sKYY4mbFosrslT0ny51yFSbZLtvnc04dmR0Q8ccAYJkMfL4t-IIGrrKR bDB6x52_gqJ8REgbhfiN6StM6jwiv_UydOjLXvFpsl5_5AZWWubNaIzj-4eCIpPFYjxBaO Gcs0FsmD1irBDIAIQodidYoI6aA" ] }
Developer produces metadata statement based on client registration request
{ "redirect_uris": [ "https://example.com/rp1/callback" ], "metadata_statement_uris": { "https://swamid.sunet.se/": "https://dev.example.com/rp1/idfed/swamid.jws", } }
The RP sends a client registration request to the OP
The OP fetches the metadata statement from the URI 'https://dev.example.com/rp1/idfed/swamid.jws' and then goes about unpacking the metadata. At this point in time the OP doesn't have the necessary key to verify the signature of the metadata. Therefor it has to unpack the JWT without verifying the signature. It will then get a JSON document looking like whats listed in step 6 above. From this document it can extract the metadata statement which should be signed by a key belonging to the FO. The OP should have the fetched the public version of that key from the FO at some time prior to this. It can now verify the signature of the metadata statement and unpack the JWT. The JSON document it then gets is the one listed in step 3. The signing key specified in that document can now be extracted and used to verify the signature of the metadata.
What's remaining now for the OP is to put all the pieces of the client registration request together. It will have one piece from the level 0 request augmented with the federation policy and then another piece from the RP.
Copyright (c) 2016 The OpenID Foundation.
The OpenID Foundation (OIDF) grants to any Contributor, developer, implementer, or other interested party a non-exclusive, royalty free, worldwide copyright license to reproduce, prepare derivative works from, distribute, perform and display, this Implementers Draft or Final Specification solely for the purposes of (i) developing specifications, and (ii) implementing Implementers Drafts and Final Specifications based on such documents, provided that attribution be made to the OIDF as the source of the material, but that such attribution does not indicate an endorsement by the OIDF.
The technology described in this specification was made available from contributions from various sources, including members of the OpenID Foundation and others. Although the OpenID Foundation has taken steps to help ensure that the technology is available for distribution, it takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this specification or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any independent effort to identify any such rights. The OpenID Foundation and the contributors to this specification make no (and hereby expressly disclaim any) warranties (express, implied, or otherwise), including implied warranties of merchantability, non-infringement, fitness for a particular purpose, or title, related to this specification, and the entire risk as to implementing this specification is assumed by the implementer. The OpenID Intellectual Property Rights policy requires contributors to offer a patent promise not to assert certain patent claims against other contributors and against implementers. The OpenID Foundation invites any interested party to bring to its attention any copyrights, patents, patent applications, or other proprietary rights that may cover technology that may be required to practice this specification.
[[ To be removed from the approved specification ]]
-01
-00