offline access and approval_prompt=force

3,088 views
Skip to first unread message

Isaac Cambron

unread,
Dec 11, 2011, 12:51:14 PM12/11/11
to oauth...@googlegroups.com
I noticed recently that new users on my app were no longer being provided refresh tokens, and several other behavior changes. I just figured out there were some big OAuth2 changes and that explains everything I'm seeing.

I understand that I can fix my refresh_token issue by asking for offline access. I'll have to force existing users to click through via approval_prompt=force if I don't have their refresh tokens. But I'm wondering why that last step is necessary. I'd have thought asking for offline access would count as a privilege escalation and automatically give the user a prompt. It feels like a bug in auto-approval: Google is basically telling my app it has the access it asked for, even though it doesn't.

Or am I missing something?

Justin Smith

unread,
Dec 11, 2011, 1:13:32 PM12/11/11
to oauth...@googlegroups.com
If you have a valid refresh token for a user, you don't have to ask for a new one.

Does your application need continual access to a Google API for a particular user? For example, your app might want to check the Contacts API in the background (without the user being present). If that's the case, then you'll want to request offline access. If that's not the case, then you don't need it.

With this change, we're trying to give the user more visibility into the permissions they are granting your application.

hemp

unread,
Dec 12, 2011, 4:07:32 PM12/12/11
to oauth...@googlegroups.com
We would like to have the ability to request a refresh_token without forcing a user approval request. There is no security reason why the approval is necessary; once they've approved an app for a given scope, then it is approved. That's how the user sees it, that's how we see it, and it doesn't change just because we're asking to be given a refresh_token.

I realize providing a refresh_token isn't necessary in the scenarios you've worked up, but there are other use cases where it is. I was excited about the announced change to eliminate the repeated approval prompts, but as it's currently implemented the unnecessary refresh_token restriction prevents us from offering users that experience without a major redesign.

hemp

unread,
Dec 12, 2011, 4:12:29 PM12/12/11
to oauth...@googlegroups.com
To clarify my request:

In the case where a user has already granted approval for offline access and a refresh_token has already been provided, we still desire the option to request a refresh_token without forcing an additional approval prompt.

Breno de Medeiros

unread,
Dec 12, 2011, 5:19:47 PM12/12/11
to oauth...@googlegroups.com
On Mon, Dec 12, 2011 at 13:12, hemp <sh...@hempel.cx> wrote:
> To clarify my request:
>
> In the case where a user has already granted approval for offline access and
> a refresh_token has already been provided, we still desire the option to
> request a refresh_token without forcing an additional approval prompt.

For security reasons we do not plan to allow that.

>
> On Monday, December 12, 2011 1:07:32 PM UTC-8, hemp wrote:
>>
>> We would like to have the ability to request a refresh_token without
>> forcing a user approval request.

--
--Breno

Isaac Cambron

unread,
Dec 12, 2011, 6:12:45 PM12/12/11
to oauth2-dev
Right, so there are two issues here:

1. Asking for offline access doesn't automatically provide a user
dialog if the user has previously approved non-offline access to the
same scope
2. Auto-approve doesn't provide a refresh_token, even if the user has
approved offline access

1 is an issue purely because it's not obvious to the developer. It's
not a huge deal because if we're doing offline access, we not actually
sending the user back through the auth endpoint, so we can get around
this by just always specifying the force option. It's just that we
have to know to do this, and it seems weird.

2 is the problem hemp is discussing, which is the other side of the
same coin. It shouldn't actually come up in production, because once
you have offline access, you should have a refresh token and you
shouldn't ever hit the auth endpoint. But for dev/test work it's a
huge hassle, since a we'd typically reset our databases, losing our
persisted refresh tokens. To get them back, we have to add the force
option. At a higher level, it's a really confusing API contract:
sometimes the auth endpoint provides a refresh token and sometimes it
doesn't, and the variable isn't the permissions being requested, but
rather whether the user has previously approved the request.
Generally, I think it's much simpler if auto-approval provides the
same data to the app as click through. You say you don't plan to allow
that for "security reasons", but that doesn't make any sense to me;
either the user has approved offline access or she hasn't.

My conclusion from both items is that it's necessary to always specify
approval_prompt=force when requesting offline access, or else you get
really inconsistent results. If you guys are sticking to that model,
then why not just make requests for offline access *always* show the
dialog? That's not my ideal, but it would be simpler for everyone, I
think.

Breno de Medeiros

unread,
Dec 12, 2011, 6:23:09 PM12/12/11
to oauth...@googlegroups.com
On Mon, Dec 12, 2011 at 15:12, Isaac Cambron <icam...@gmail.com> wrote:
> Right, so there are two issues here:
>
> 1. Asking for offline access doesn't automatically provide a user
> dialog if the user has previously approved non-offline access to the
> same scope
> 2. Auto-approve doesn't provide a refresh_token, even if the user has
> approved offline access
>
> 1 is an issue purely because it's not obvious to the developer. It's
> not a huge deal because if we're doing offline access, we not actually
> sending the user back through the auth endpoint, so we can get around
> this by just always specifying the force option. It's just that we
> have to know to do this, and it seems weird.
>
> 2 is the problem hemp is discussing, which is the other side of the
> same coin. It shouldn't actually come up in production, because once
> you have offline access, you should have a refresh token and you
> shouldn't ever hit the auth endpoint. But for dev/test work it's a
> huge hassle, since a we'd typically reset our databases, losing our
> persisted refresh tokens.

To make our server in sync with our test servers, you should revoke
the tokens in the server. That's what we'd hope you do in production
too if the user choose to 'de-authorize' in your site.

> To get them back, we have to add the force
> option. At a higher level, it's a really confusing API contract:
> sometimes the auth endpoint provides a refresh token and sometimes it
> doesn't, and the variable isn't the permissions being requested, but
> rather whether the user has previously approved the request.
> Generally, I think it's much simpler if auto-approval provides the
> same data to the app as click through. You say you don't plan to allow
> that for "security reasons", but that doesn't make any sense to me;
> either the user has approved offline access or she hasn't.

refresh_tokens are like scoped passwords. Issuing them transparently
without user intervention is a significant security risk, whether or
not users approved the application.

>
> My conclusion from both items is that it's necessary to always specify
> approval_prompt=force when requesting offline access, or else you get
> really inconsistent results.

Not really. See below.

> If you guys are sticking to that model,
> then why not just make requests for offline access *always* show the
> dialog? That's not my ideal, but it would be simpler for everyone, I
> think.

There are some cases (e.g., when the user is signing into the
application and granting authorization at the same time), where it's
impossible for the app to decide ahead of time (because it doesn't
know the identity of the user yet) whether this is a first approval,
or subsequent auto-approval. Also in this case it's fundamental that
auto-approval works (a prompt always for login is an unnacceptable
user experience).

>
> On Dec 12, 5:19 pm, Breno de Medeiros <br...@google.com> wrote:
>> On Mon, Dec 12, 2011 at 13:12, hemp <sh...@hempel.cx> wrote:
>> > To clarify my request:
>>
>> > In the case where a user has already granted approval for offline access and
>> > a refresh_token has already been provided, we still desire the option to
>> > request a refresh_token without forcing an additional approval prompt.
>>
>> For security reasons we do not plan to allow that.
>>
>>
>>
>> > On Monday, December 12, 2011 1:07:32 PM UTC-8, hemp wrote:
>>
>> >> We would like to have the ability to request a refresh_token without
>> >> forcing a user approval request.
>>
>> --
>> --Breno

--
--Breno

Isaac Cambron

unread,
Dec 12, 2011, 7:16:53 PM12/12/11
to oauth2-dev
>There are some cases (e.g., when the user is signing into the application and granting authorization at the same time), where it's impossible for the app to decide ahead of time (because it doesn't know the identity of the user yet) whether this is a first approval, or subsequent auto-approval. Also in this case it's fundamental that auto-approval works (a prompt always for login is an unnacceptable user experience).

Right, that's exactly the problem: if I don't know whether the request
is going to be auto-approved or not, I don't know whether or not I'm
going to receive a refresh token. Again, that can be worked around,
but having the the oauth endpoint respond differently based on a
variable the app has no access to is a difficult interface.

On Dec 12, 6:23 pm, Breno de Medeiros <br...@google.com> wrote:

Breno de Medeiros

unread,
Dec 12, 2011, 7:21:11 PM12/12/11
to oauth...@googlegroups.com
On Mon, Dec 12, 2011 at 16:16, Isaac Cambron <icam...@gmail.com> wrote:
>>There are some cases (e.g., when the user is signing into the application and granting authorization at the same time), where it's impossible for the app to decide ahead of time (because it doesn't know the identity of the user yet) whether this is a first approval, or subsequent auto-approval. Also in this case it's fundamental that auto-approval works (a prompt always for login is an unnacceptable user experience).
>
> Right, that's exactly the problem: if I don't know whether the request
> is going to be auto-approved or not, I don't know whether or not I'm
> going to receive a refresh token. Again, that can be worked around,
> but having the the oauth endpoint respond differently based on a
> variable the app has no access to is a difficult interface.

I meant this as an example why access_type=offline does _not_ imply in
approval_prompt=force; Some applications will want to use both. Some
will only want to use access_type=offline (I expect this to be the
more common situation, actually). In the vast majority of the cases,
this causes no real issues in production, as the default behavior is
exactly what the application needs.

--
--Breno

Isaac Cambron

unread,
Dec 12, 2011, 8:00:53 PM12/12/11
to oauth2-dev
OK, I guess I can see that. I'll also take your word for it that
providing a refresh token as part of auto-approve is a security issue
(though I still don't get it). In any case, it's still an unintuitive
interface for the developer, since it's stateful in a non-obvious way.

One thing you mentioned is that in testing, I should be revoking
access for the user instead of forcing the dialog. That makes sense,
but is there a way to do that programmatically, or do I have to do
that from the user's account settings page?

On Dec 12, 7:21 pm, Breno de Medeiros <br...@google.com> wrote:

Breno de Medeiros

unread,
Dec 12, 2011, 8:42:39 PM12/12/11
to oauth...@googlegroups.com
On Mon, Dec 12, 2011 at 17:00, Isaac Cambron <icam...@gmail.com> wrote:
> OK, I guess I can see that. I'll also take your word for it that
> providing a refresh token as part of auto-approve is a security issue
> (though I still don't get it). In any case, it's still an unintuitive
> interface for the developer, since it's stateful in a non-obvious way.
>
> One thing you mentioned is that in testing, I should be revoking
> access for the user instead of forcing the dialog. That makes sense,
> but is there a way to do that programmatically, or do I have to do
> that from the user's account settings page?

Yes, programmatically you can use the revoke endpoint. Using POST:

curl "https://accounts.google.com/o/oauth2revoke" -d
"token=$refresh_token_to_revoke"

--
--Breno

Breno de Medeiros

unread,
Dec 12, 2011, 8:45:10 PM12/12/11
to oauth...@googlegroups.com
On Mon, Dec 12, 2011 at 17:42, Breno de Medeiros <br...@google.com> wrote:
> On Mon, Dec 12, 2011 at 17:00, Isaac Cambron <icam...@gmail.com> wrote:
>> OK, I guess I can see that. I'll also take your word for it that
>> providing a refresh token as part of auto-approve is a security issue
>> (though I still don't get it). In any case, it's still an unintuitive
>> interface for the developer, since it's stateful in a non-obvious way.
>>
>> One thing you mentioned is that in testing, I should be revoking
>> access for the user instead of forcing the dialog. That makes sense,
>> but is there a way to do that programmatically, or do I have to do
>> that from the user's account settings page?
>
> Yes, programmatically you can use the revoke endpoint. Using POST:
>
> curl "https://accounts.google.com/o/oauth2revoke" -d
> "token=$refresh_token_to_revoke"

Sorry, there was an error of cut-and-paste in my response. Should be:

curl "https://accounts.google.com/o/oauth2/revoke" -d
"token=$refresh_token_to_revoke"

i.e., the revocation endpoint is accounts.google.com/o/oauth2/revoke
(notice the '/' between 'oauth2' and 'revoke')

--
--Breno

Isaac Cambron

unread,
Dec 13, 2011, 2:18:55 AM12/13/11
to oauth2-dev
I'll try that out. Thanks!

On Dec 12, 8:45 pm, Breno de Medeiros <br...@google.com> wrote:
> On Mon, Dec 12, 2011 at 17:42, Breno de Medeiros <br...@google.com> wrote:
>

hemp

unread,
Dec 14, 2011, 1:58:12 PM12/14/11
to oauth2-dev
On Dec 12, 2:19 pm, Breno de Medeiros <br...@google.com> wrote:
> On Mon, Dec 12, 2011 at 13:12, hemp <sh...@hempel.cx> wrote:
> > In the case where a user has already granted approval for offline access and
> > a refresh_token has already been provided, we still desire the option to
> > request a refresh_token without forcing an additional approval prompt.
>
> For security reasons we do not plan to allow that.

It would be edifying for the community if you could explain the
security implications of this. Which weakness in your authentication
scheme would a system exploit in order to request a refresh_token that
doesn't belong to them?

I will give a counter example. I know you folks and Facebook don't see
eye to eye on much, but Facebook's OAuth implementation does not use
refresh tokens and not only is it possible, but the normal case, that
they return auth tokens for offline access without prompting the user
again for approval. I'm actually not aware of any OAuth2
implementation except Google's which refuses to grant an offline auth
token for a logged in user without force-prompting them. The OAuth v2
(22) spec lists refresh tokens themselves as optional (ie: not a
security risk.)

This strikes me as a somewhat arbitrary decision. To dismiss our
requests to change it for unexplained "security reasons" seems odd.

Thanks for your time. I do appreciate that you are monitoring and
responding to this thread. Ultimately we are beholden to your
implementation; I simply prefer if usability prevails over presumption
in API design.

Breno de Medeiros

unread,
Dec 14, 2011, 5:32:02 PM12/14/11
to oauth...@googlegroups.com
I think the ground of the conversation is shifting a bit. I am trying
to help you find a secure solution for your use case.

Your main consideration is that you'd like to share authentication
state between a web application and a native application. Is that
correct?

--
--Breno

Shawn Hempel

unread,
Dec 14, 2011, 6:22:47 PM12/14/11
to oauth...@googlegroups.com
That was actually someone else's use case from this thread. For us to accommodate the auto-approve model you've implemented, we would have to re-architect our authentication system. Since this is an app already in production, that's simply not worthwhile.

As a result, we have to force approval every time the user logs in. I understand that we are not using your new model as it was designed to be used, but you should understand that your new model didn't exist when we built our app.

When you disabled our app by making a breaking change (defaulting to not returning a refresh_token) - that set me off in a bad mood to start with. Then I got excited when I discovered that the upside of your change was that we could potentially eliminate users having to re-approve constantly, only to discover that we can't take advantage of it without a bunch of work on our end.

All in all, I'd say I don't feel like these changes were in any way positive for us. You are free to ignore my request; we will just continue with forced approval and a poor user experience when Google auth is used.

Breno de Medeiros

unread,
Dec 14, 2011, 6:38:32 PM12/14/11
to oauth...@googlegroups.com
On Wed, Dec 14, 2011 at 15:22, Shawn Hempel <sh...@hempel.cx> wrote:
> That was actually someone else's use case from this thread. For us
> to accommodate the auto-approve model you've implemented, we would have to
> re-architect our authentication system. Since this is an app already in
> production, that's simply not worthwhile.
>
> As a result, we have to force approval every time the user logs in. I
> understand that we are not using your new model as it was designed to be
> used, but you should understand that your new model didn't exist when we
> built our app.
>
> When you disabled our app by making a breaking change (defaulting to not
> returning a refresh_token) - that set me off in a bad mood to start with.
> Then I got excited when I discovered that the upside of your change was that
> we could potentially eliminate users having to re-approve constantly, only
> to discover that we can't take advantage of it without a bunch of work on
> our end.
>
> All in all, I'd say I don't feel like these changes were in any way positive
> for us. You are free to ignore my request; we will just continue with forced
> approval and a poor user experience when Google auth is used.

I am sorry for how things played out with our application. We
announced these changes in the blog and in this mailing list on Nov.
10: https://groups.google.com/forum/#!searchin/oauth2-dev/just...@google.com/oauth2-dev/_kqhtqqCbLg/XzgyAHGEASwJ
; It may have been too late for your application or you may have
missed the announcement.

Note that Google's OAuth2 API will soon leave the "Experimental"
status and that means more predictability moving forward.

--
--Breno

Justin Smith

unread,
Dec 14, 2011, 6:51:54 PM12/14/11
to oauth...@googlegroups.com
There's no ignoring going on. 

I'd really like to hear how the changes are causing a lot of work. I can see how taking advantage of the feature would cause some work, but I'd imagine the offline scenario is something like:
a) UserA kicks off the flow, perhaps as part of the authentication to your site. User sees consent page.
b) your app exchanges the authorization code & receives a refresh token
c) you app stores the refresh token for future use.

... time goes by ...

d) User A returns to your app & kicks off the same flow. No consent reqd.
e) your app exchanges the authorization code for an access token

Which part of that is causing lots of work? Is it storing the refresh token?

Shawn Hempel

unread,
Dec 14, 2011, 7:24:23 PM12/14/11
to oauth...@googlegroups.com
On Wed, Dec 14, 2011 at 3:38 PM, Breno de Medeiros <br...@google.com> wrote:
I am sorry for how things played out with our application. We
announced these changes in the blog and in this mailing list on Nov.
10: https://groups.google.com/forum/#!searchin/oauth2-dev/just...@google.com/oauth2-dev/_kqhtqqCbLg/XzgyAHGEASwJ
; It may have been too late for your application or you may have
missed the announcement.

We missed the announcement. I only found this group (and that blog entry) after our site stopped working. I'm glad for them, but we weren't subscribed to either.

 
Note that Google's OAuth2 API will soon leave the "Experimental"
status and that means more predictability moving forward.

That would be much appreciated!

Shawn Hempel

unread,
Dec 15, 2011, 1:24:43 PM12/15/11
to oauth...@googlegroups.com
On Wed, Dec 14, 2011 at 3:51 PM, Justin Smith <just...@google.com> wrote:
Which part of that is causing lots of work? Is it storing the refresh token?

Our specific scenario is slightly different:

a) UserA kicks off the flow as part of the authentication to our web app. User sees consent page.
b) Web app exchanges the authorization code & receives a refresh token.
c) Web app authenticates to our backend service using the refresh token, which stores it for future use.
... time goes by ...
d) UserA returns to our web app & kicks off the same flow. No consent reqd.
e) Web app exchanges the authorization code for an access token.
f) Our backend service expects a refresh token in order to authenticate the user, but we don't have one.

Step f is where it breaks down in our environment. Because we assumed a refresh token would be available, the auth system was built to expect it. We would have to modify our backend service to support optionally taking an access token.

What we would probably end up doing eventually is to have the backend service accept an access token, use it to fetch user details, then use those details to identify the user in our database and associate an existing refresh token with it. The problem being, of course, that we then have to handle a bunch of scenarios like expired refresh tokens, etc etc. That isn't an issue if we have a valid refresh token to begin with; so the "a lot of work" it causes is not so much in coming up with a solution but getting the right people involved in making the changes and then identifying and handling all the ways it might fail.

Breno de Medeiros

unread,
Dec 15, 2011, 1:40:19 PM12/15/11
to oauth...@googlegroups.com
On Thu, Dec 15, 2011 at 10:24, Shawn Hempel <sh...@hempel.cx> wrote:
On Wed, Dec 14, 2011 at 3:51 PM, Justin Smith <just...@google.com> wrote:
Which part of that is causing lots of work? Is it storing the refresh token?

Our specific scenario is slightly different:

a) UserA kicks off the flow as part of the authentication to our web app. User sees consent page.
b) Web app exchanges the authorization code & receives a refresh token.

The Web app should not be exchanging the authorization code; this implies that you're exposing the client_secret to end users. The backend service should exchange the authorization_code.
 
c) Web app authenticates to our backend service using the refresh token, which stores it for future use.
... time goes by ...
d) UserA returns to our web app & kicks off the same flow. No consent reqd.
e) Web app exchanges the authorization code for an access token.
f) Our backend service expects a refresh token in order to authenticate the user, but we don't have one.

Step f is where it breaks down in our environment. Because we assumed a refresh token would be available, the auth system was built to expect it. We would have to modify our backend service to support optionally taking an access token.

What we would probably end up doing eventually is to have the backend service accept an access token, use it to fetch user details, then use those details to identify the user in our database and associate an existing refresh token with it. The problem being, of course, that we then have to handle a bunch of scenarios like expired refresh tokens, etc etc.

Refresh_tokens do not expire.

If they have been revoked in the meantime, the user will be prompt to approve again, and you will get a new one.
 
That isn't an issue if we have a valid refresh token to begin with; so the "a lot of work" it causes is not so much in coming up with a solution but getting the right people involved in making the changes and then identifying and handling all the ways it might fail.



--
--Breno

Shawn Hempel

unread,
Dec 15, 2011, 2:21:34 PM12/15/11
to oauth...@googlegroups.com
Thank you for your feedback Breno. I've addressed your comments below - but I want to add that you got on my case earlier for getting off topic and now you're attacking our application (based on assumptions) instead of addressing my request. I only shared what I shared because Justin asked and I thought it might help demonstrate that your view of how these APIs are being used may be incomplete; not to open a dialog about our system architecture.

- Shawn

On Thu, Dec 15, 2011 at 10:40 AM, Breno de Medeiros <br...@google.com> wrote:
The Web app should not be exchanging the authorization code; this implies that you're exposing the client_secret to end users. The backend service should exchange the authorization_code.

The web app uses the server side flow to authenticate the user; the client secret is never exposed to end users or anyone else. We don't involve our backend service until the user has been authenticated by Google and has authorized our app to call APIs on their behalf. We also have an iPad client which uses the client side work flow and the backend service must accommodate both.
 
The problem being, of course, that we then have to handle a bunch of scenarios like expired refresh tokens, etc etc.

Refresh_tokens do not expire.

That may be the covenant you've made, but we have to treat all promises as breakable - as evidenced by the recent change to stop returning refresh tokens. It was only meant as an example.

Breno de Medeiros

unread,
Dec 15, 2011, 2:46:10 PM12/15/11
to oauth...@googlegroups.com
On Thu, Dec 15, 2011 at 11:21, Shawn Hempel <sh...@hempel.cx> wrote:
Thank you for your feedback Breno. I've addressed your comments below - but I want to add that you got on my case earlier for getting off topic and now you're attacking our application (based on assumptions) instead of addressing my request.

I am trying to understand how you use our APIs so that I can give you appropriate advice. Didn't mean to sound antagonistic.

 
I only shared what I shared because Justin asked and I thought it might help demonstrate that your view of how these APIs are being used may be incomplete; not to open a dialog about our system architecture.

Glad to hear I was mistaken in understanding how your web app is architected. This brings back the point earlier of why I didn't want to give detailed examples of threats and attacks earlier.



- Shawn

On Thu, Dec 15, 2011 at 10:40 AM, Breno de Medeiros <br...@google.com> wrote:
The Web app should not be exchanging the authorization code; this implies that you're exposing the client_secret to end users. The backend service should exchange the authorization_code.

The web app uses the server side flow to authenticate the user; the client secret is never exposed to end users or anyone else. We don't involve our backend service until the user has been authenticated by Google and has authorized our app to call APIs on their behalf. We also have an iPad client which uses the client side work flow and the backend service must accommodate both.

The client-side flow is, I presume, one time and in the future the client uses the refresh_token to authenticate to your server, right? The client-side flow assumes offline access (it was not affected by these changes).

 
 
The problem being, of course, that we then have to handle a bunch of scenarios like expired refresh tokens, etc etc.

Refresh_tokens do not expire.

That may be the covenant you've made, but we have to treat all promises as breakable - as evidenced by the recent change to stop returning refresh tokens. It was only meant as an example.

In the past, there was no auto-approval of code requests; so as you architected your application, all users had to approve access on every sign-in (before and after the change). The current changes enable auto-approval and better user experience but require you to take a different way to structure your code.



--
--Breno

Justin Smith

unread,
Dec 15, 2011, 3:06:55 PM12/15/11
to oauth...@googlegroups.com
Copying from your description of the flow & an earlier post:

a) UserA kicks off the flow as part of the authentication to our web app. User sees consent page.
b) Web app exchanges the authorization code & receives a refresh token.
c) Web app authenticates to our backend service using the refresh token, which stores it for future use.
... time goes by ...
d) UserA returns to our web app & kicks off the same flow. No consent reqd.
e) Web app exchanges the authorization code for an access token.
f) Our backend service expects a refresh token in order to authenticate the user, but we don't have one.

Step f is where it breaks down in our environment. Because we assumed a refresh token would be available, the auth system was built to expect it. We would have to modify our backend service to support optionally taking an access token.
What we would probably end up doing eventually is to have the backend service accept an access token, use it to fetch user details, then use those details to identify the user in our database and associate an existing refresh token with it. The problem being, of course, that we then have to handle a bunch of scenarios like expired refresh tokens, etc etc. That isn't an issue if we have a valid refresh token to begin with; so the "a lot of work" it causes is not so much in coming up with a solution but getting the right people involved in making the changes and then identifying and handling all the ways it might fail.

Step (c) - how does the Web app use the refresh token to authenticate to your backend? Is it just the presence of the refresh token, or are you trying to do some sort of validation on it?

BTW - thanks for taking the time to describe all of this. We have not done a great job with our documentation by describing how this is designed to work in your applications. I'm working on that and more complete information is coming. Unfortunately this information doesn't help you in your current situation. A refresh token is for exactly one thing: obtaining new access tokens for offline scenarios (e.g. backup service, or something that doesn't require a user at the browser). Encoding more meaning isn't something I would advise - as mentioned before, this is hard to pick up from the docs at the moment.

Shawn Hempel

unread,
Dec 15, 2011, 3:07:01 PM12/15/11
to oauth...@googlegroups.com
On Thu, Dec 15, 2011 at 11:46 AM, Breno de Medeiros <br...@google.com> wrote:
I am trying to understand how you use our APIs so that I can give you appropriate advice. Didn't mean to sound antagonistic.

Understood. Email can be problematic that way.

Glad to hear I was mistaken in understanding how your web app is architected. This brings back the point earlier of why I didn't want to give detailed examples of threats and attacks earlier.

Well, there is a slight difference - I'm not implementing a public spec for a system designed to protect the global identity of individuals. I think calling out reasons why implementing this spec in any other way introduces security risks would be good for the internet as a whole so we can challenge those companies who are doing it differently. It would also suggest that the spec should be changed so as not to list refresh tokens as entirely optional.

 
The client-side flow is, I presume, one time and in the future the client uses the refresh_token to authenticate to your server, right? The client-side flow assumes offline access (it was not affected by these changes).

Yes, the client side flow is irrelevant except to explain why our backend service was desgined to authenticate users given a refresh token (for the reason you just described.) The web app was conceived after the iPad app and therefore it uses the same auth mechanisms.


In the past, there was no auto-approval of code requests; so as you architected your application, all users had to approve access on every sign-in (before and after the change). The current changes enable auto-approval and better user experience but require you to take a different way to structure your code.

That is correct. This whole dialog is about me trying to explain why the design decision made causes us not to be able to take advantage of this much desired new feature without reworking our app. It is entirely self-serving. I thought I made that obvious from the start! :) My justification was that since no one has identified an actual security risk associated with providing the refresh token, we're being forced to do extra work for no known reason. It isn't an attack or a criticism - it's a request meant only to simplify life for your API consumers, myself included.

And with that I think we've come full circle. I don't think there's any more context I can add without giving away too detailed information about our authentication and I think you have enough to understand our use case. I'm not expecting anything to change, but I remain hopeful.

Thank you Breno and Justin for your time and consideration. I've enjoyed this earnest discourse.

- Shawn

Nischal Shetty

unread,
Dec 16, 2011, 5:02:31 AM12/16/11
to oauth...@googlegroups.com
Why introduce the refresh_token concept at all? oAuth 2.0 aims to make things simpler and keeping the refresh_token away would be a much better thing to do. I really think you guys should sit and take a call on this. 

I've been developing an open source java library called face4j for facebook and it's been so easy to integrate oAuth 2.0 introduced in the facebook Graph API. I've seen the refresh_token concept causing a lot of heartache among developers. It's creating a confusion that can and I personally believe should be fixed.

I would request you once again, please do take a few minutes to discuss this among yourselves and try to do away with the refresh_token concept.

oAuth 2.0 (with offline access) from my view:

1. User lands on your login page
2. Redirect user to google
3. Google displays approval page (only first time, auto approval if previous token not revoked)
4. User redirected back to your app with a "code"
5. Your app exchanges "code" for long lived "access_token"


Reply all
Reply to author
Forward
0 new messages