Subject: [OAUTH-WG] unregistered clients (was: User-agent flow and pre-registered redirect_uri)

From: Marius Scurtescu <[email-masked]>
Date: Fri, 11 Jun 2010 08:20:07 -0700

On Fri, Jun 11, 2010 at 8:05 AM, Justin Richer <[email-masked]> wrote:
> Along these lines, I'd like to propose an extension for per-client
> instance information to be passed from a client to the server. Things
> like a human-readable client name/description, instance name/description
> (could be tied to host name, ip, label like "home" or "Work"), and even
> something like a display icon. This is especially useful for things like
> device clients (where I might have a bunch of devices with the same
> client ID) or unregistered clients, where the client id string ends up
> being closer to a user-agent string from a browser than a trusted
> identifier, especially since it can't have a reliable secret.

Yes, I think something like this is definitely needed. I suggested an
optional client_name parameter exactly for this purpose. For OAuth 1
Google is using a custom parameter.

> Speaking of which, the spec is relatively quiet on registered vs.
> unregistered clients. I'd like to see the WG maybe pull together some
> guidance on this topic? I'm not sure what form that would take though,
> an information note that sits along with the RFC? A page on the oauth
> wiki? Basically, I think we can get away from the anonymous/anonymous
> hack that Google used with OAuth1 since we're not requiring the client
> secret for signing anymore. Thoughts?

Yes, the secret does not need to be set to "anonymous" anymore, but
the client_id still needs a special value in order to signal
unregistered mode. Either that, or yet one more parameter, but that
could be going too far.

Not sure if we can standardize on a value, like "anonymous". It
depends what current implementations are using. I think it is
perfectly fine for the authz server to define this special client_id.

If we want to move all this to an extension, I still think it should
be rather in core, then I can write it up.

Marius

>
>  -- Justin
>
>
> On Fri, 2010-06-11 at 10:38 -0400, George Fletcher wrote:
>> Makes perfect sense as we have the same model for our clients &
>> tokens:)
>>
>> The one use case we've encountered is that this model revokes the
>> tokens for all clients with the same client_id. So if I've got three
>> of the same client installed (on three computers) and they likely all
>> have the same client_id, then revoking that client_id affects all
>> three clients. I think this is a reasonable trade-off. Especially
>> since revoking authorizations will be an infrequent event.
>>
>> Thanks,
>> George
>>
>> On 6/10/10 11:35 AM, Andrew Arnott wrote:
>> > Thanks Marius.
>> >
>> > I've answered your question below.
>> >
>> > On Wed, Jun 9, 2010 at 9:35 AM, Marius Scurtescu
>> > <[email-masked]> wrote:
>> >         > I've always considered an authorization as a tuple of
>> >         > client_id,user,scope,issue_date.  If an authorization has
>> >         been approved, and
>> >         > another request for authorization for a subset of the
>> >         scope previously
>> >         > issued comes in, the auth server can skip the interactive
>> >         user authorization
>> >         > and just approve the request since nothing new is being
>> >         issued.
>> >
>> >
>> >         The tuple seems right, except for the issue date, why would
>> >         you add that?
>> >
>> > The issue_date enables to scenarios: expiring tokens and token
>> > revocation.  Here's how, for each scenario:
>> >
>> > Obviously to know if a token has expired you need to know when it
>> > was issued.  Or, you can forget the issue date and just store the
>> > expiration date in the token. I choose to go with an issue date
>> > (plus an optional expected lifetime) because it gives more ability
>> > in the future to say "oops, we had a security weakness in all tokens
>> > issued prior to [date], so let's consider all earlier tokens
>> > invalid."  It's harder to say that when all you have are expiration
>> > dates because you don't know how old the token is.  This is just the
>> > way I chose to do it, but I know there are other ways.
>> >
>> > Now let's look at how you revoke issued tokens.  One of the nice
>> > things enabled by OAuth 2.0 is that the authorization server and
>> > resource server never have to store tokens if they are appropriate
>> > signed by the auth server.  This is great because (among other
>> > things) clients with little-to-no ability to persistently store
>> > tokens may ask for tokens frequently, and that could bog down an
>> > auth server with storing all those issued tokens.  But how can a
>> > user revoke a previously authorized token if no one but the client
>> > knows what the tokens are? (thought question)  My solution to this
>> > is that instead of thinking about revoking tokens, the user revokes
>> > authorizations.  The user goes through his account on the
>> > authorization server and sees a list of clients and what they are
>> > authorized to do.  Note that this only requires the auth server to
>> > store this authorization tuple -- not the actual issued tokens.  If
>> > the user clicks "revoke" on one of these authorizations, that row is
>> > deleted in the database.  Issued tokens (both refresh and access
>> > tokens) have this same tuple encoded in them.
>> > Now, when a refresh token is used to obtain a new short-lived access
>> > token (and you could do this on every access token use as well if
>> > you wanted) the token is of course signature-validated, but it is
>> > also checked that the authorization tuple has a matching tuple in
>> > the auth server's database.  If it's missing, then that
>> > authorization has been revoked and the token is thereby invalidated.
>> > So why the issue date?  Because suppose the user has authorized a
>> > client and then that client's tokens are compromised (stolen
>> > computer perhaps).  The user will of course revoke authorization for
>> > that client.  The user then gets a new copy of that client (perhaps
>> > a new computer) and authorizes it.  Whoops.  Now all those
>> > invalidated tokens are valid again because the authorization tuple
>> > exists.  Except now the issue date on the authorization on the auth
>> > server is newer than in the refresh token on the invalidated client.
>> > That's why issue date is such a critical part of an authorization
>> > tuple.  Any token issued prior to the earliest authorization on
>> > record at the auth server represents a revoked authorization, and
>> > without an issue date in the tuple there's no way to recognize that.
>> >
>> > At least that's the way I'm seeing it.  I hope that makes sense.
>> >
>> >
>> > _______________________________________________
>> > OAuth mailing list
>> > [email-masked]
>> > https://www.ietf.org/mailman/listinfo/oauth
>> >
>
>
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth
>

---

From: "William Mills" <[email-masked]>
Date: Fri, 11 Jun 2010 08:44:29 -0700

I am in favor of an optional client_name parameter.  I think a client_id parameter of the form of an HTTP URL, effecttively reserving the prefix http:// would be sufficient to indicate an unregistered client ID.  The URL could then point to either a favicon type image or an XML doc more fully describing the client.

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] 
> On Behalf Of Marius Scurtescu
> Sent: Friday, June 11, 2010 8:20 AM
> To: Justin Richer
> Cc: [email-masked]
> Subject: [OAUTH-WG] unregistered clients (was: User-agent 
> flow andpre-registered redirect_uri)
> 
> > like a human-readable client name/description, instance 
> > name/description (could be tied to host name, ip, label 
> like "home" or 
> > "Work"), and even something like a display icon. This is especially 
> > useful for things like device clients (where I might have a 
> bunch of 
> > devices with the same client ID) or unregistered clients, where the 
> > client id string ends up being closer to a user-agent string from a 
> > browser than a trusted identifier, especially since it 
> can't have a reliable secret.
> 
> Yes, I think something like this is definitely needed. I 
> suggested an optional client_name parameter exactly for this 
> purpose. For OAuth 1 Google is using a custom parameter.
> 
> 
> Yes, the secret does not need to be set to "anonymous" 
> anymore, but the client_id still needs a special value in 
> order to signal unregistered mode. Either that, or yet one 
> more parameter, but that could be going too far.
> 
> Not sure if we can standardize on a value, like "anonymous". 
> It depends what current implementations are using. I think it 
> is perfectly fine for the authz server to define this special 
> client_id.
> 
> If we want to move all this to an extension, I still think it 
> should be rather in core, then I can write it up.
> 
> Marius
> 
> >
> >  -- Justin
> >
> >
> >> > in the future to say "oops, we had a security weakness in all 
> >> > tokens issued prior to [date], so let's consider all 
> earlier tokens 
> >> > dates because you don't know how old the token is.  This is just 
> >> > the way I chose to do it, but I know there are other ways.
> >> >
> >> > the user clicks "revoke" on one of these authorizations, 
> that row 
> >> > is deleted in the database.  Issued tokens (both refresh 
> and access
> >> > Now, when a refresh token is used to obtain a new short-lived 
> >> > access token (and you could do this on every access token use as 
> >> > well if you wanted) the token is of course 
> signature-validated, but 
> >> > it is also checked that the authorization tuple has a matching 
> >> > tuple in the auth server's database.  If it's missing, then that 
> >> > computer perhaps).  The user will of course revoke authorization 
> >> > for that client.  The user then gets a new copy of that client 
> >> > (perhaps a new computer) and authorizes it.  Whoops.  
> Now all those