should we use refresh tokens?

12 views
Skip to first unread message

Michiel de Jong

unread,
Apr 29, 2012, 9:22:33 AM4/29/12
to unhosted
Francois' remoteStorage server gives out access token that expire. We
could use a token endpoint with CORS so that the app can refresh the
access token using a refresh token
(http://tools.ietf.org/html/draft-ietf-oauth-v2-13#section-6 )

i wonder whether this is useful, however:
http://stackoverflow.com/questions/3487991/why-does-oauth-v2-have-both-access-and-refresh-tokens

should we use refresh tokens?

Michiel de Jong

unread,
Apr 29, 2012, 9:36:42 AM4/29/12
to unhosted
it seems to me refresh tokens don't make a lot of sense in the
implicit grant flow, although they would still protect against for
instance an access token leaking when the resource server, but not the
authorization server, is compromised.

"When using the implicit grant type flow a refresh token is not
returned which requires repeating the authorization process once the
access token expires."
http://tools.ietf.org/html/draft-ietf-oauth-v2-25#page-48 seems to
indicate that the spec doesn't even allow for refresh tokens in
implicit grant flow,

but also http://tools.ietf.org/html/draft-ietf-oauth-v2-25#section-10.4
gives some more background.

on the whole, i would say that if the app gets an unexpected 403 from
the resource server, it should inform the user by displaying a "more
credentials needed" button. it needs to be a button, so that we can
open the 'allow' dialog from the onclick handler

François Kooman

unread,
Apr 29, 2012, 3:59:06 PM4/29/12
to unho...@googlegroups.com, Michiel de Jong
On 4/29/12 3:36 PM, Michiel de Jong wrote:
> "When using the implicit grant type flow a refresh token is not
> returned which requires repeating the authorization process once the
> access token expires."
> http://tools.ietf.org/html/draft-ietf-oauth-v2-25#page-48 seems to
> indicate that the spec doesn't even allow for refresh tokens in
> implicit grant flow,

Exactly :)

> on the whole, i would say that if the app gets an unexpected 403 from
> the resource server, it should inform the user by displaying a "more
> credentials needed" button. it needs to be a button, so that we can
> open the 'allow' dialog from the onclick handler

See https://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-19#section-3.1

An expired token results in "invalid_token", which returns a 401
Unauthorized.

An "insufficient_scope" returns a 403 Forbidden, which is a different error.

In the case the access token is expired the client can just return
(redirect browser) to the authorization server to request a new access
token. The user already approved this request and thus this involves no
user interaction at all. So no need to create a new button whatsoever.

Regards,
François
Francois_Kooman.vcf

Michiel de Jong

unread,
Apr 29, 2012, 5:13:11 PM4/29/12
to François Kooman, unho...@googlegroups.com
On Sun, Apr 29, 2012 at 9:59 PM, François Kooman
<Francoi...@surfnet.nl> wrote:
> The user already approved this request and thus this involves no
> user interaction at all. So no need to create a new button whatsoever.

it's impossible to open a popup from javascript unless it's directly
in a click handler. this is because popup blockers look at the call
depth. the assumption is that if you open a popup when a user clicks
something, it is likely that the user wanted that popup to be opened.
whereas if you do it at a random moment (e.g. when the page loads,
before the user clicks anyhting) it's likely to be popup spam.

so we do need the button click. we could display 'session expired
(reconnect)' in the syncer UI. I'll discuss the exact way to present
this to the user with Jan tomorrow.


Cheers!
Michiel

François Kooman

unread,
Apr 30, 2012, 4:16:41 AM4/30/12
to Michiel de Jong, unho...@googlegroups.com
On 4/29/12 11:13 PM, Michiel de Jong wrote:
> it's impossible to open a popup from javascript unless it's directly
> in a click handler. this is because popup blockers look at the call
> depth. the assumption is that if you open a popup when a user clicks
> something, it is likely that the user wanted that popup to be opened.
> whereas if you do it at a random moment (e.g. when the page loads,
> before the user clicks anyhting) it's likely to be popup spam.

I guess it would be best to get rid of this popup altogether. Are you
sure it is *really* needed? I mean, the application can run at
index.html, the (re)direct script can be callback.html and take care of
everything. There is no need for a popup as far as I can see. And if
there is no need for a popup then there is no problem by redirecting the
user...

Regards,
François
Francois_Kooman.vcf

Michiel de Jong

unread,
Apr 30, 2012, 4:23:47 AM4/30/12
to François Kooman, unho...@googlegroups.com
On Mon, Apr 30, 2012 at 10:16 AM, François Kooman
<Francoi...@surfnet.nl> wrote:
> On 4/29/12 11:13 PM, Michiel de Jong wrote:
>> it's impossible to open a popup from javascript unless it's directly
>
> redirecting the user...

that's worse! you can't suddenly send the user to another URL while
they are in the middle of using a one-page app.

François Kooman

unread,
Apr 30, 2012, 4:26:25 AM4/30/12
to Michiel de Jong, unho...@googlegroups.com
On 4/30/12 10:23 AM, Michiel de Jong wrote:
> that's worse! you can't suddenly send the user to another URL while
> they are in the middle of using a one-page app.

Well, still no need for a popup, but not sure it would be really a
problem assuming you make sure all data is stored (in localStorage).

What do you propose for access token validity? 8h?

Regards,
François

Francois_Kooman.vcf

Javier Díaz Esteban

unread,
Apr 30, 2012, 7:11:24 AM4/30/12
to unho...@googlegroups.com, Michiel de Jong, unho...@googlegroups.com
I've been following the popup issue whenever there's any external
interactionq since the beginning and I think it should be inline.
Either a modal window or the login button itself expands to show the
info inside, but there should be a standard way of telling the user,
that the user recognizes without having to read it, and all the
providers or apps connecting to this should follow those guidelines.

Opening new popups or redirecting the user is a crime against UX and
good taste.

Sent from my iPhone

On 30.04.2012, at 16:26, François Kooman <Francoi...@surfnet.nl>
wrote:
> <Francois_Kooman.vcf>

Jan-Christoph Borchardt

unread,
Apr 30, 2012, 10:00:40 AM4/30/12
to unho...@googlegroups.com
Nice to see you on here again Javi!
And I totally agree, popups are invasive.

The real problem here seems to be the decision to expire tokens. This
is a security issue that should not be offloaded to users by just
expiring them. Nothing is as annyoing as needing to sign in again or
having a message saying you that the session is expired.

Just a first thought about another solution (which is also a bit
invasive though). Just expire the tokens when a previously not known
machine is used. This would be done through checking navigator etc.
via Javascript, and this is also the reason I don’t like this
approach.

In any case, we should not give people shit work by needing to click
»yeah I still want to use the app damnit, what do you think? Connect
me again already!« every now and then.

Michiel de Jong

unread,
Apr 30, 2012, 12:14:02 PM4/30/12
to unho...@googlegroups.com
Francois, what if you expire the tokens after they have not been used
for 8 hours? that way you can finish your current session, at least. i
agree with Jan that expiring a token while the user has a session open
in an app is annoying.

about the pop-up vs in-tab dance, i guess both are possible, and i
don't know which one is more invasive. i'll make it configurable for
now. lightboxes are not an option, since they don't display the url in
the address bar.

François Kooman

unread,
Apr 30, 2012, 12:17:56 PM4/30/12
to unho...@googlegroups.com, Michiel de Jong
On 4/30/12 6:14 PM, Michiel de Jong wrote:
> Francois, what if you expire the tokens after they have not been used
> for 8 hours? that way you can finish your current session, at least. i
> agree with Jan that expiring a token while the user has a session open
> in an app is annoying.

I guess you could do that, but that is not OAuth then.

> about the pop-up vs in-tab dance, i guess both are possible, and i
> don't know which one is more invasive. i'll make it configurable for
> now. lightboxes are not an option, since they don't display the url in
> the address bar.

I wonder how bad it is to play the redirect game (it takes usually less
than a second) once every 1/4/8 hrs. If you make sure localStorage
retains all data that should really not be a problem... Note, this is
exactly the same for SAML sessions and that doesn't seem to cause any
problems...

Surely you can implement some "idle" detection that refreshes an access
token when the user is not doing anything and the token is about to
expire...

Regards,
François
Francois_Kooman.vcf

Jan-Christoph Borchardt

unread,
Apr 30, 2012, 2:23:20 PM4/30/12
to unho...@googlegroups.com, Michiel de Jong
What would then happen after these 8 hours? You would have to OAuth
the app at the storage again, right?
(And it doesn’t matter if you properly disconnected or not – after 8
hours of you will get disconnected automatically, right?)

François Kooman

unread,
Apr 30, 2012, 2:49:43 PM4/30/12
to unho...@googlegroups.com, Jan-Christoph Borchardt, Michiel de Jong
On 4/30/12 8:23 PM, Jan-Christoph Borchardt wrote:
> What would then happen after these 8 hours?

The request for PUT, GET or DELETE to the storage endpoint will fail
with a HTTP 401 response (Unauthorized), if you did not anticipate the
expiry of the access token.

> You would have to OAuth
> the app at the storage again, right?

Yes. Just redirect the browser to the authorize endpoint and catch the
access token on the redirect_uri and update the access token in your
localStorage.

> (And it doesn’t matter if you properly disconnected or not – after 8
> hours of you will get disconnected automatically, right?)

What is properly disconnected? The access token would remain valid for 8
hours no matter what. If you start a new browser sessions, e.g. private
mode, or use a different browser, you would get a fresh token that is
valid for 8 hrs as well. Or you mean something else?

Regards,
François
Francois_Kooman.vcf

Michiel de Jong

unread,
Apr 30, 2012, 2:52:38 PM4/30/12
to François Kooman, unho...@googlegroups.com
On Mon, Apr 30, 2012 at 6:17 PM, François Kooman
<Francoi...@surfnet.nl> wrote:
> On 4/30/12 6:14 PM, Michiel de Jong wrote:
>> Francois, what if you expire the tokens after they have not been used
>> for 8 hours? that way you can finish your current session, at least. i
>> agree with Jan that expiring a token while the user has a session open
>> in an app is annoying.
>
> I guess you could do that, but that is not OAuth then.

why not? i would say the resource server could notify the
authorization server whether token is being used, and the
authorization server is free to display this information to the user
and also to factor that information into its automated decisions.

>
>> about the pop-up vs in-tab dance, i guess both are possible, and i
>> don't know which one is more invasive. i'll make it configurable for
>> now. lightboxes are not an option, since they don't display the url in
>> the address bar.
>
> I wonder how bad it is to play the redirect game (it takes usually less
> than a second) once every 1/4/8 hrs. If you make sure localStorage
> retains all data that should really not be a problem...

i guess if the library sees a token expiry coming, it could wait for a
button click and open an unsolicited popup, but it is definitely ugly
and not ideal. and the question is when it's in the user's interest to
automatically expire tokens. i think this is when they haven't been
used for say 2 months, or when the user is deleted. if the user is
deleted then ideally all access tokens could be deleted immediately.
this may be more difficult in surfnet's case, but generally speaking i
think it would be better.

so really what we're trying to solve here is not double-checking
whether the OAuth grant is still valid, but rather checking whether
the SAML grant from the IdP to the auth server is still valid.

> Note, this is
> exactly the same for SAML sessions and that doesn't seem to cause any
> problems...
>

maybe we can do better than SAML. i think UX is really important

> Surely you can implement some "idle" detection that refreshes an access
> token when the user is not doing anything and the token is about to
> expire...

but why is it useful? with this, the app signals to the remoteStorage
that it's still active. the remoteStorage can also know this by
looking at the activity on the storage server

Jan-Christoph Borchardt

unread,
Apr 30, 2012, 3:16:48 PM4/30/12
to unho...@googlegroups.com, François Kooman
On Mon, Apr 30, 2012 at 8:52 PM, Michiel de Jong <mic...@unhosted.org> wrote:
> and the question is when it's in the user's interest to
> automatically expire tokens. i think this is when they haven't been
> used for say 2 months, or when the user is deleted.

Exactly this is the core question. Instead of deciding beforehand that
expiration is a good thing, and putting an arbitrary cap of »say, 8
hours« onto it, we should do it from the other way round.

So what is exactly what we try to prevent? If I understood correctly,
the case would be:
I am on a shared computer, and connect my storage to an app. After I’m
finished working, I close the app without disconnecting. This leaves
my token available to others.
But the token is not the problem here. What seems more important here
is that people actually sign out of the storage server, for instance
log out of their 5apps. Otherwise there would be completely different
attack vectors.

Expiring the token on the client is similar to a web app that would
ask every now and then for you to confirm that you are, in fact, still
interested in using the app. This is highly annyoing and should not at
all be the default behavior. Even after 8 hours of sleep I don’t want
to double-confirm – all my apps, every morning.


> maybe we can do better than SAML. i think UX is really important

Yes and double yes. The baseline is not existing systems, but a
flawless experience.

François Kooman

unread,
Apr 30, 2012, 3:17:44 PM4/30/12
to Michiel de Jong, unho...@googlegroups.com
On 4/30/12 8:52 PM, Michiel de Jong wrote:
> why not? i would say the resource server could notify the
> authorization server whether token is being used, and the
> authorization server is free to display this information to the user
> and also to factor that information into its automated decisions.

I would recommend against having an (extra) communication channel
between the RS and AS and making stuff way more complicated, keep it as
simple as possible...

> i guess if the library sees a token expiry coming, it could wait for a
> button click and open an unsolicited popup, but it is definitely ugly
> and not ideal.

Yes, we should get rid of this popup idea completely, it is terribly
user unfriendly and annoying, BrowserID is bad enough ;-) DO NOT WANT.

> and the question is when it's in the user's interest to
> automatically expire tokens. i think this is when they haven't been
> used for say 2 months, or when the user is deleted. if the user is
> deleted then ideally all access tokens could be deleted immediately.
> this may be more difficult in surfnet's case, but generally speaking i
> think it would be better.

Well, you *could* have tokens that do not expire, but only are revoked
when the user takes away the application's permissions. That may work
for the general case, but won't in our SAML case and I wouldn't want
that for my personal server either.

> so really what we're trying to solve here is not double-checking
> whether the OAuth grant is still valid, but rather checking whether
> the SAML grant from the IdP to the auth server is still valid.

True. However, changing secrets occasionally makes perfect sense from a
security POV (in case they leak from your browser, which seems not that
unreasonable).

> maybe we can do better than SAML. i think UX is really important

Exactly, NO POPUPS! :)

> but why is it useful? with this, the app signals to the remoteStorage
> that it's still active. the remoteStorage can also know this by
> looking at the activity on the storage server

Access tokens have (and should have) a fixed validity, no fluid validity.

Regards,
François
Francois_Kooman.vcf

François Kooman

unread,
Apr 30, 2012, 3:24:32 PM4/30/12
to unho...@googlegroups.com, Jan-Christoph Borchardt
On 4/30/12 9:16 PM, Jan-Christoph Borchardt wrote:
> So what is exactly what we try to prevent? If I understood correctly,
> the case would be:
> I am on a shared computer, and connect my storage to an app. After I’m
> finished working, I close the app without disconnecting. This leaves
> my token available to others.

Actually, I would remove all OAuth tokens when the user closes the
browser (use sessionStorage instead of localStorage), and not only when
using the "disconnect" button. (Incidentally, this is also needed for
SAML and is what we train our users to do: close your browser when you
are done and everything will be fine)...

> But the token is not the problem here. What seems more important here
> is that people actually sign out of the storage server, for instance
> log out of their 5apps. Otherwise there would be completely different
> attack vectors.

It is a problem to logout of all applications when you have 10 of them
open and you want to leave the shared computer. Just closing your
browser and be done would make much more sense. The next best thing
would be to have the app you want to logout from also ask if you want to
logout from all other apps you are currently using...

> Expiring the token on the client is similar to a web app that would
> ask every now and then for you to confirm that you are, in fact, still
> interested in using the app. This is highly annyoing and should not at
> all be the default behavior. Even after 8 hours of sleep I don’t want
> to double-confirm – all my apps, every morning.

My suggestion would not involve giving permissions at all, only after
you manually revoke authorization for the given app.

> Yes and double yes. The baseline is not existing systems, but a
> flawless experience.

Agreed. However, some reasonable security should still be there, or we
might as well remove OAuth... this 8h token limit is something we @
SURFnet would probably want to enforce (either 8h or when the user
closes browser).

Regards,
François
Francois_Kooman.vcf
Reply all
Reply to author
Forward
0 new messages