[Openid-specs-ab] About ID Tokens being access tokens
John Bradley
ve7jtb at ve7jtb.com
Mon Aug 29 21:38:36 UTC 2011
As far as I know the token endpoint trades code for a access and refresh token, or a refresh token for an access token.
There is no scope parameter for the token endpoint only the authorization one.
I think there is a basic requirement to be able to get the id_token to the RP via the redirect response, so it can start rendering a page before it makes the subsequent calls to the token and user-info endpoints.
John B.
On 2011-08-29, at 1:34 PM, Nat Sakimura wrote:
> Andreas,
>
> I do not think OAuth sends 'scope' with Access Token Request. In the
> flow you describe, you are sending 'scope' with 'code' to the Token
> Endpoint. If it does, it can be used to exchange a one time access
> token 'code' to 'id_token' and 'access_token' on a separate call of
> the Token Endpoint as you describe, but I am not sure if we have an
> extension point there.
>
> =nat
>
> 2011/8/30 Andreas Åkre Solberg <andreas.solberg at uninett.no>:
>> On 26. aug.2011, at 20:27, John Bradley wrote:
>>
>> An important issue for RP is perceived latency. That is why they don't want
>> to have to do a extra round trip to get the id_token.
>>
>> That is a very good argument.
>>
>> If you have a JS client that needs an access token as well as a id_token it
>> would need to make two separate implicit calls to at the authorization
>> endpoint.
>> I suspect that is the biggest problem.
>>
>> In the 'OAuth approach', there is no way of obtaining multiple tokens in the
>> implicit flow; the oauth approach would in this flow issue a multi-scope
>> token to the RP. This could make things much simpler to JS clients. It could
>> be a simpler and smarter way - or it could be a showstopper; anyone with
>> first-hand knowledge to the implicit flow use case that can elaborate a bit
>> on this?
>> Note that by issuing a multi-scoped token ( the OAuth way ) in the implicit
>> flow; we solve the issue mentioned earlier about the necessity to include a
>> hash of the access token in the id_token.
>> Actually in OAuth implicit grant flow, you are NOT allowed to return both an
>> access token and a refresh token; and I suspect that the reasoning behind
>> this is the exact same that we run into with id_token and access token.
>>
>> For a server it is also several round trips that each may require user
>> consent. From a user experience point of view one trip to the OP is enough.
>>
>> No, there is no additional front-channel round trips in the proposal.
>> Instead some backchannel calls are added to retrieve tokens, and id token +
>> user data.
>>
>> We are running into a OAuth issue. There should be a standard way to
>> request multiple tokens.
>>
>> There is; (you may request multiple scopes in the request) and I'm
>> suggesting that we use it. What there is not, is a way to requset multiple
>> tokens and receive them all at the same time.
>>
>> In the case where you only want code in the redirect, scope is about the
>> only place to say that you want a access token for the user-info endpoint
>> and a id_token returned from the token endpoint.
>>
>> That was why I was proposing that the openid scope be about the id_token and
>> we define other scopes for user-info.
>>
>> Great, that is a brilliant idea :) And this is also what I am suggesting :)
>>
>> That way scope controls what tokens you want (perhaps others for portable
>> contacts etc), and response_type controls how you get them.
>>
>> Exactly.
>>
>> There was a proposal to the allow multiple access tokens to be returned by
>> making it an array or structure.
>> That didn't happen, so we are on our own to define how multiple tokens are
>> returned.
>>
>> If we need them returned all at once.
>>
>> That makes it more complicated to use standard libraries. I don't think
>> we are the only ones with this issue
>>
>> The other issue with treating a id_token as an access token is that some
>> frameworks don't make it easy to get at the contents of the token used to
>> authenticate to the endpoint.
>> I suspect that is going to be a problem with them using any sort of JWT as
>> an access token.
>>
>> Yup. The response of the token endpoint is most likely handled all by the
>> OAuth client library, and it should follow the OAuth spec section 4.2.2:
>> The client SHOULD ignore unrecognized response parameters.
>>
>> And I assume there it is a significant probability that these unrecognized
>> response parameters are accessilble through the client library API.
>> This also is pointing in the direction of beeing more streamlined with
>> OAuth.
>> Some arguments pro this approach:
>> * Simpler spec, easier to understand.
>> No confusion of what is a token, and is a 'token' to be decoded or used as
>> if it were an access token…
>> * Simpler to implement, more re-use of OAuth library.
>> Some arguments against this approach:
>> * Additonal back-channel calls to resolve tokens, and tokens to JWT.
>> * Potentially a showstopper with a multi-purpose token in the implicit flow?
>> Here is an example of how the flows may look like (I hope it do not include
>> too many errors):
>>
>> Walkthrough of the OpenID Connect more streamlined with OAuth-Approach
>>
>> Using the OAuth approach of obtaining two tokens (by the use of a refresh
>> token), we gain the flexibility of both having the user data token and the
>> session (id) token as two completely independent tokens; and in other use
>> cases (like in implicit grant) have a shared multi-scoped token for use on
>> both services.
>>
>> Authorization Code Flow
>>
>> Client prepares an authorization request:
>>
>> GET /authorization?
>> response_type=code&
>> cliend_id=ab1&
>> scope=openid-session%20openid-userdata HTTP/1.1
>> Host: rp.example.com
>>
>> The user logs in, performs consent, etc. and the user agent is redirected
>> back to the RP with the following response:
>>
>> GET /callback?
>> code=BBB3330
>> Host: consumer.example.org
>>
>> Obtaining an session access token, and getting the ID Token
>>
>> The client uses the access token endpoint to resolve
>> an openid-session token:
>>
>> POST /token
>> Host: rp.example.org
>> Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
>> Content-Type: application/x-www-form-urlencoded;charset=UTF-8
>>
>> grant_type=authorization_code&
>> code=BBB3330&
>> scope=openid-session
>>
>> The provider responds by issuing an openid-session access token, and also
>> an refresh_token.
>>
>> HTTP/1.1 200 OK
>> Content-Type: application/json;charset=UTF-8 Cache-Control: no-store
>> Pragma: no-cache
>> {
>> "access_token":"2YotnFZFEjr1zCsicMWpAA",
>> "token_type":"bearer",
>> "scope": "openid-session",
>> "expires_in":3600,
>> "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
>> }
>>
>> Note: the openid-session access token is transparent and NOT an JWT. It may
>> be exchanged for a JWT using the check session service.
>>
>> The provider obtains the ID Token using the openid-session access token;
>> performing a request to the check session endpoint; a basic OAuth protected
>> endpoint:
>>
>> POST /check_session HTTP/1.1
>> Accept: application/jwt
>> Authorization: Basic 2YotnFZFEjr1zCsicMWpAA
>> Content-Type: application/x-www-form-urlencoded
>> Content-Length: 0
>>
>> The provider returns an JWT (because of the Accept header, may also return
>> unsigned JSON):
>>
>> Content-Type: application/jwt;charset=UTF-8
>>
>> eyJpc3MiOi.Jqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogIm.h0dHA6Ly9le
>>
>> And the returned JWT may be decoded (and validated) by the client to
>> something like:
>>
>> {
>> "issuer":"http://server.example.com",
>> "client_id","http://client.example.com",
>> "audience", "http://client.example.com",
>> "user_id":"user_328723",
>> "exp":1303852880
>> }
>>
>> Obtaining an user data access token, and getting the user data
>>
>> The client uses the already obtained refresh_token when accessing the OAuth
>> Token Service, and requests the scope openid-userdata:
>>
>> POST /token
>> Host: rp.example.org
>> Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
>> Content-Type: application/x-www-form-urlencoded;charset=UTF-8
>>
>> grant_type=refresh_token&
>> refresh_token=tGzv3JOkF0XG5Qx2TlKWIA&
>> scope=openid-userdata
>>
>> The provider responds by issuing an openid-userdata Access Token:
>>
>> HTTP/1.1 200 OK
>> Content-Type: application/json;charset=UTF-8 Cache-Control: no-store
>> Pragma: no-cache
>> {
>> "access_token":"2YotnFZFEjr1zCsicMWpAA",
>> "scope": "openid-userdata",
>> "token_type":"bearer",
>> "expires_in":3600,
>> }
>>
>> The consumer, uses the OAuth protected user data endpoint to retrieve user
>> data:
>>
>> POST /user_info HTTP/1.1
>> Accept: application/jwt
>> Authorization: Basic 2YotnFZFEjr1zCsicMWpAA
>> Content-Type: application/x-www-form-urlencoded
>>
>> schema=openid
>>
>> The provider returns an JWT (because of the Accept header, may also return
>> unsigned JSON):
>>
>> Content-Type: application/jwt;charset=UTF-8
>>
>> eyJpc3MiOi.Jqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogIm.h0dHA6Ly9le
>>
>> And the returned JWT may be decoded (and validated) by the client to
>> something like:
>>
>> {
>> "id": "90125",
>> "name": "Jonathan Q. Doe"
>> "given_name": "Jonathan",
>> "middle_name": "Q.",
>> "family_name": "Doe",
>> "nickname": "John",
>> "email": "johndoe at example.com",
>> "verified": true,
>> "profile": "http://example.com/johndoe/",
>> "picture": "http://example.com/johndoe/me.jpg",
>> "website": "http://john.doe.blogs.example.net/",
>> "gender": "male",
>> "birthday": "05/02/0000",
>> "zoneinfo": "America/Los_Angeles"
>> "locale": "en_US",
>> "phone_number": "+1 (425) 555-1212",
>> "address": {
>> "region": "WA",
>> "country": "United States"
>> },
>> "last_updated": "2011-06-29T21:10:22+0000"
>> }
>>
>> Implicit Flow
>>
>> The consumer, performs an authentication request:
>>
>> GET /authorization?
>> response_type=token&
>> cliend_id=ab1&
>> scope=openid-session%20openid-userdata HTTP/1.1
>> Host: rp.example.com
>>
>> The user logs in, performs consent, etc. and the user agent is redirected
>> back to the RP with the following response:
>>
>> HTTP/1.1 302 Found
>> Location:
>> http://consumer.example.org/callback#access_token=2YotnFZFEjr1zCsicMWpAA
>> &scope=openid-session%20openid-userdata&state=xyz&token_type=bearer&expires_in=3600
>>
>> Then the consumer got an Access Token that is valid at both the User Data
>> service and at the Session Service.
>>
>> The user agent may send the access token to the web protected resource, and
>> the web protected resource will use the access token with both the user info
>> and session info service.
>>
>> _______________________________________________
>> Openid-specs-ab mailing list
>> Openid-specs-ab at lists.openid.net
>> http://lists.openid.net/mailman/listinfo/openid-specs-ab
>>
>>
>
>
>
> --
> Nat Sakimura (=nat)
> Chairman, OpenID Foundation
> http://nat.sakimura.org/
> @_nat_en
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4767 bytes
Desc: not available
URL: <http://lists.openid.net/pipermail/openid-specs-ab/attachments/20110829/64f38f02/attachment.p7s>
More information about the Openid-specs-ab
mailing list