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

Vladimir Dzhuvinov vladimir at connect2id.com
Wed Aug 1 19:26:46 UTC 2018


Just added a comment to the ticket to consider putting the code into the
JWT claims set. That way client developers will not be able to skip or
ignore the JWT processing, e.g. by treating the response as a regular
code response. Having the code inside the JWT will also make it possible
to apply additional encryption (JWE), if there's a need to hide the code
from the end-user / browser.

Vladimir


On 01/08/18 11:56, Torsten Lodderstedt via Openid-specs-fapi wrote:
> 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
>
>
> _______________________________________________
> Openid-specs-fapi mailing list
> Openid-specs-fapi at lists.openid.net
> http://lists.openid.net/mailman/listinfo/openid-specs-fapi


-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4002 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.openid.net/pipermail/openid-specs-fapi/attachments/20180801/28116792/attachment-0001.p7s>


More information about the Openid-specs-fapi mailing list