On May 6, 2019, at 1:42 PM, Emond Papegaaij <emond.papega...@gmail.com> wrote:
> 
> Hi all,
> 
> For a browser-based app, we try to follow the recommendations set in draft-
> ietf-oauth-browser-based-apps-01. This does allow us to create a secure OAuth 
> 2.0 browser-based application, but at the moment it comes at a cost wrt. user 
> experience when the access token expires. Our current solution forces us to 
> redirect the user to the authorization server for a new authorization code. 
> This will destroy most state the browser-based app has, causing the user to 
> loose data. We are looking for a way to get a new access token in a secure 
> way 
> without disrupting the user.
> As a refresh token is not issued to the app (as it should be), the 
> application 
> is forced to do a front-channel re-authentication for an authorization code. 
> We are thinking of letting this front-channel communication happen in a 
> hidden 
> iframe. Naturally, this can only be done if no user interaction is required, 
> hence we want to use the OIDC prompt=none. Is this a viable way of doing this 
> re-authentication? Can it hurt to open up our authorization server for non-
> interactive authorization requests inside an iframe? At the moment we do not 
> allow iframes at all.

Some AS implementations will block authentication in an iframe, but will allow 
you to use the OIDC prompt=none. This is already used quite often today by 
implicit apps. It is possible that AS implementations may allow iframes in the 
future, by detecting the frame is not covered with any buttons, and having the 
authentication be based on phishing-resistant authentication methods like W3C 
Web Authentication.

You could also trigger re-authorization with a user click, thus allowing 
opening the AS in a new window or tab. Once back on the site via callback, the 
temporary/pop-up window can do things like exchange the code for an access 
token, persist it, postMessage the original window, do window.close, etc.

The iframe and pop-up methods together can be used in lieu of persisting state 
across a redirect to the ISP. Many apps after reaching a sufficient level of 
complexity just wind up persisting the page state in some combination of local 
and remote storage, however. Javascript state is very brittle and will be 
broken by things as simple as a page refresh.

Native apps which opened the system browser had at least the capability of this 
problem as well - the application could be unloaded from memory/quit between 
when authentication started and ended.

On the other hand, refresh tokens IMHO are given quite a bit more fear in 
browser apps than warranted. It really depends on the AS - whether it can tie 
refresh tokens to the user’s authentication, or if they are tied to a long-term 
/ persisted / "offline” authorization independent of an active user 
authentication. Currently, the latter is more common in implementations, and 
doesn’t make sense for browser applications. This doesn’t mean refresh tokens 
are automatically discounted for all environments.

Given the choice between an 8 hour access token, or a 10 minute access token 
and a refresh token that will expire at a maximum of 8 hours, the second 
provides quite a few more options to be more secure. (eg. checking backing user 
session and revocation, checking for updates to client blacklist, the rotation 
of the access token, rotating refresh tokens to prevent use by more than one 
client, expiring access on inactivity based on lag in refreshing, and so on).

If the refresh token is tied to the AS concept of user session, then it mostly 
replaces the ‘hidden iframe’ use above - you’ll only have your refresh token 
expire when the AS is asking for user presence on the front channel, presumably 
for interaction. Although, I suppose in some environments there could be a 
non-interactive reauthentication/factor as well (such as kerberos, MTLS, or 
re-verifying user location via geoip) where a hidden iframe might still provide 
UX benefit.

Browser based apps are significantly more vulnerable to code injection attacks 
than native apps (although don’t believe native apps are immune), so it may 
make sense for an AS to have a stricter default policy for browser-based 
applications than they would have for a native app. It also could make sense to 
allow for more scopes or longer-lived tokens for an audited, first-party 
browser-based application. Restrictions may be opened up even more for 
applications/browsers which also use PoP methods to prevent key exfiltration.

OAuth is nice in that the AS consolidates those responsibilities, however the 
flip side of that is that a client developer is really dependent on an AS to   
provide a combination of features juggling good security and user experience.

> Maybe anybody knows a different way of achieving this? As I cannot believe we 
> are the only ones facing this issue, maybe a recommendation can be put in the 
> spec?

I think so far it has been an omission since this isn’t a “new” problem - 
implicit has the same issues and a subset of techniques (the difference bineg 
the capability to use refresh tokens now). However, it makes sense to document 
current practices in a BCP document :-)

WRT refresh tokens: I’m at the start of an independent blog post on considering 
token policies and lifetimes, but I expect it to take some time to polish and 
to get through reviewer feedback before publishing.

-DW
_______________________________________________
OAuth mailing list
OAuth@ietf.org
https://www.ietf.org/mailman/listinfo/oauth

Reply via email to