[Openid-specs-fapi] Issue #155: Support authorization and identity federation use cases for the same client_id (openid/fapi)

Torsten Lodderstedt issues-reply at bitbucket.org
Wed Aug 1 08:56:00 UTC 2018


New issue 155: Support authorization and identity federation use cases for the same client_id
https://bitbucket.org/openid/fapi/issues/155/support-authorization-and-identity

Torsten Lodderstedt:

FAPI part 2 uses the scope value "openid" in conjunction with the response types "code id_token" or "code id_token token" to turn on the detached signature over the authorization response. This design forces OPs to always provide a RP/client with a sub value even if the particular use case is API access authorization (e.g. payment initiation). In such a use case, most implementations provide the client with an ephemeral sub value (reasons to be clarified, hypothesis: privacy/data minimization/liability/no identity data in psd 2 regulatory context). 

This creates the challenge that the same OP cannot provide a real, long-lasting user id to the same client simply because the same client does not have a means to indicate its desire. 

The proposal is, to disentangle detached signature and identity federation by introducing a new response type to trigger the creation of a detached signature. The openid scope then can be used as usual in OpenId Connect to request identity data. 
Note: the nonce parameter should be utilized as well because it can, in combination with the detached signature, provide replay detection (no need for PKCE).

response type signed_code
This response type will cause the OP/AS to respond with a JWT containing the following claims:

{  
   "iss":"https://accounts.example.com",
   "aud":"s6BhdRkqt3",
   "jti":"2730dc2f-c9c6-4be4-97c9-6223d18f2b13",
   "nonce":"n-0S6_WzA2Mj",
   "exp":1311281970,
   "c_hash":"4422E0E094F34E97C852EB5F9B2839D8120066C27EF66AA28C3DDC7CE7A79815",
   "s_hash":"44D41668D199FF3D525FA357A25525D738AADF2A7B1E2C819A39E38500ABAED9"
}

The client can use the payload to verify the integrity of the response as well as the sender and proper audience. This response type can be used with and without the scope openid.

Example: API access authorization 

The request uses the new response type along with nonce and an API specific scope value. In this case, this is a scope value as used by the Berlin Group's OAuth mode. 

GET /authorise?responseType=signed_code&
client_id=s6BhdRkqt3&
redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&
scope=pis:f0bbf1fd-2857-4e1b-a403-9fd1dc171183&
state= S8NJ7uqk5fY4EjNvP_G_FtyJu6pUsvH9jsYni9dMAJw&
nonce=n-0S6_WzA2Mj HTTP/1.1
Host: accounts.example-bank.com

The AS/OP responds with code and state and also includes a signature object,

GET /cb?code=PyyFaux2o7Q0YfXBU32jhw.5FXSQpvr8akv9CeRDSd0QA&
state=S8NJ7uqk5fY4EjNvP_G_FtyJu6pUsvH9jsYni9dMAJw&
signature=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmV4YW1wbGUuY29tIiwiYXVkIjoiczZCaGRSa3F0MyIsImp0aSI6IjI3MzBkYzJmLWM5YzYtNGJlNC05N2M5LTYyMjNkMThmMmIxMyIsIm5vbmNlIjoibi0wUzZfV3pBMk1qIiwiZXhwIjoxMzExMjgxOTcwLCJjX2hhc2giOiI0NDIyRTBFMDk0RjM0RTk3Qzg1MkVCNUY5QjI4MzlEODEyMDA2NkMyN0VGNjZBQTI4QzNEREM3Q0U3QTc5ODE1Iiwic19oYXNoIjoiNDRENDE2NjhEMTk5RkYzRDUyNUZBMzU3QTI1NTI1RDczOEFBREYyQTdCMUUyQzgxOUEzOUUzODUwMEFCQUVEOSJ9.ldPh3w3QAkkbz3voa3F2pvruWQwNBv3AYV9xpcuVLZi5Da4tjep-xayjO4_flznYuu9EZbyYA1lb9uzu0rSSSiwEJ5Ms9ZEvB4l1xXNLT5TRV00erXb6Y1JsvxHjanB0I8-FUHdP-HMA0Zhg9UVohAc2qiO6wDcEfi5y_1fST4Y
Host: client.example.com

that contains the following data:

{  
   "iss":"https://accounts.example.com",
   "aud":"s6BhdRkqt3",
   "jti":"2730dc2f-c9c6-4be4-97c9-6223d18f2b13",
   "nonce":"n-0S6_WzA2Mj",
   "exp":1311281970,
   "c_hash":"4422E0E094F34E97C852EB5F9B2839D8120066C27EF66AA28C3DDC7CE7A79815",
   "s_hash":"44D41668D199FF3D525FA357A25525D738AADF2A7B1E2C819A39E38500ABAED9"
}

The client/RP performs all the checks as defined in FAPI part 1&2 on iss, s_hash, c_hash and nonce in order to detect replay and mix up.

It then uses the code to obtain the access token. 

{  
   "iss":"https://accounts.example.com",
   "aud":"s6BhdRkqt3",
   "jti":"2730dc2f-c9c6-4be4-97c9-6223d18f2b13",
   "nonce":"n-0S6_WzA2Mj",
   "exp":1311281970,
   "c_hash":"4422E0E094F34E97C852EB5F9B2839D8120066C27EF66AA28C3DDC7CE7A79815",
   "s_hash":"44D41668D199FF3D525FA357A25525D738AADF2A7B1E2C819A39E38500ABAED9"
}

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

grant_type=authorization_code&code=PyyFaux2o7Q0YfXBU32jhw.5FXSQpvr8akv9CeRDSd0QA
&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{  
   "access_token":"SlAV32hkKG",
   "token_type":"Bearer",
   "expires_in":3600
}

Example identity federation/data

The RP uses the same response type, this time combined with the scope "openid email profile", which asks for a sub value along with the email address and profile data of the user. 
 
GET /authorise?responseType=signed_code&
client_id=s6BhdRkqt3&
redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&
scope=openid%20email%20profile&
state= S8NJ7uqk5fY4EjNvP_G_FtyJu6pUsvH9jsYni9dMAJw&
nonce=n-0S6_WzA2Mj HTTP/1.1
Host: accounts.example-bank.com

Response from the OP and response validation works the same as in the first example. 

GET /cb?code=PyyFaux2o7Q0YfXBU32jhw.5FXSQpvr8akv9CeRDSd0QA&
state=S8NJ7uqk5fY4EjNvP_G_FtyJu6pUsvH9jsYni9dMAJw&
signature=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmV4YW1wbGUuY29tIiwiYXVkIjoiczZCaGRSa3F0MyIsImp0aSI6IjI3MzBkYzJmLWM5YzYtNGJlNC05N2M5LTYyMjNkMThmMmIxMyIsIm5vbmNlIjoibi0wUzZfV3pBMk1qIiwiZXhwIjoxMzExMjgxOTcwLCJjX2hhc2giOiI0NDIyRTBFMDk0RjM0RTk3Qzg1MkVCNUY5QjI4MzlEODEyMDA2NkMyN0VGNjZBQTI4QzNEREM3Q0U3QTc5ODE1Iiwic19oYXNoIjoiNDRENDE2NjhEMTk5RkYzRDUyNUZBMzU3QTI1NTI1RDczOEFBREYyQTdCMUUyQzgxOUEzOUUzODUwMEFCQUVEOSJ9.ldPh3w3QAkkbz3voa3F2pvruWQwNBv3AYV9xpcuVLZi5Da4tjep-xayjO4_flznYuu9EZbyYA1lb9uzu0rSSSiwEJ5Ms9ZEvB4l1xXNLT5TRV00erXb6Y1JsvxHjanB0I8-FUHdP-HMA0Zhg9UVohAc2qiO6wDcEfi5y_1fST4Y
Host: client.example.com

The RP exchanges the code for access and (this time) id token.

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

grant_type=authorization_code&code=PyyFaux2o7Q0YfXBU32jhw.5FXSQpvr8akv9CeRDSd0QA
&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{  
   "access_token":"SlAV32hkKG",
   "token_type":"Bearer",
   "expires_in":3600,
   "id_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmV4YW1wbGUuY29tIiwic3ViIjoiMjQ0MDAzMjAiLCJhdWQiOiJzNkJoZFJrcXQzIiwibm9uY2UiOiJuLTBTNl9XekEyTWoiLCJleHAiOjEzMTEyODE5NzAsImlhdCI6MTMxMTI4MDk3MCwiYXV0aF90aW1lIjoxMzExMjgwOTY5LCJhY3IiOiJ1cm46bWFjZTppbmNvbW1vbjppYXA6c2lsdmVyIn0.culBs939W3NjZ-WhDIvmtKuia-RFK-MghASHWLst62mLFh7qoSXBlQu0INKOfCXx6Zn9ZT8dLJFb93IxUyrwQty5tNHM8L28AdXNt6WXhOdFAf3EGx-bXmXLzfSdluvPAgWMkLHTA2YhX_zI5XfKJxq439mVXpFqJnnh6TRkTjU"
}

The ID Token contains the usual data including sub 

{  
   "iss":"https://accounts.example.com",
   "sub":"24400320",
   "aud":"s6BhdRkqt3",
   "nonce":"n-0S6_WzA2Mj",
   "exp":1311281970,
   "iat":1311280970,
   "auth_time":1311280969,
   "acr":"urn:mace:incommon:iap:silver"
}

Note: basically nonce could be omited as it had already been conveyed by the detached signature.

The client then uses the access token to obtain the user data:

GET /userinfo HTTP/1.1
Host: accounts.example.com
Authorization: Bearer SlAV32hkKG

HTTP/1.1 200 OK
Content-Type: application/json

{  
   "sub":"248289761001",
   "name":"Jane Doe",
   "given_name":"Jane",
   "family_name":"Doe",
   "preferred_username":"j.doe",
   "email":"janedoe at example.com",
   "picture":"http://example.com/janedoe/me.jpg"
}

Example: combination

Surely, both aspects could be combined.

GET /authorise?responseType=signed_code&
client_id=s6BhdRkqt3&
redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&
scope=openid%20email%20profile%20ais%3Af0bbf1fd-2857-4e1b-a403-9fd1dc171183&
state= S8NJ7uqk5fY4EjNvP_G_FtyJu6pUsvH9jsYni9dMAJw&
nonce=n-0S6_WzA2Mj HTTP/1.1
Host: accounts.example-bank.com




More information about the Openid-specs-fapi mailing list