A Primer on OAuth2 for Client-Side Applications: Part 4
- By Johann Nallathamby
- 25 May, 2020
This is the final article of my four part series on OAuth2 for client side applications (CSAs). I started this series by discussing the broader categories of CSAss and their legacy, more recent authentication and API authorization standards, and their pros and cons. In the second part, I discussed the challenges in CSAs, standard and non-standard recommendations that are widely employed to overcome these challenges and some non-standard solution patterns for single page applications (SPA) to overcome limitations in the existing standards I’ve discussed in part 1, specifically OAuth 2.0 proxy patterns. In the third article, I discussed the important security properties of cookies that make them a suitable candidate for a sender-constrained token technology and more non-standard solution patterns, specifically sender-constrained token patterns.
This article will focus on the latest and upcoming standards that follow a sender-constrained token pattern aimed at solving the challenges in CSAs and solution patterns being employed to improve CSA user experiences.
More Sender-Constrained Token Patterns
These are some of the latest and upcoming standards following sender-constrained token patterns:
- OAuth 2.0 Token Binding
- OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens
- OAuth 2.0 Demonstration of Proof-of-Possession at the Application Layer (DPoP)
OAuth 2.0 Token Binding
More recently a set of specifications has emerged that allows you to implement sender-constrained token patterns. The first one in this set to emerge was the OAuth 2.0 Token Binding specification, which extends from the Token Binding for HTTP (RFC ) specification.
Unfortunately, Token Binding for HTTP, on which the “OAuth 2.0 Token Binding” specification was based, suffered an important setback when Chrome announced that they would be dropping the support for it , iOS never committed to implementation. Hence, the technology is not widely adopted as of yet.
OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens
The next specification to emerge from the sender-constrained token technologies set of specifications is the OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (RFC 8705).
This specification provides a mechanism for OAuth 2.0 clients to authenticate using mutual TLS with X.509 certificates, based on self-signed certificates or public key infrastructure (PKI) to the OAuth 2.0 authorization server, and obtain access and refresh tokens that are bound to the OAuth 2.0 client’s certificate. This way the OAuth 2.0 protected resources are provided a mechanism for ensuring that an access token presented to them for accessing a resource was legitimately obtained by the sender of that access token. The same applies to the OAuth 2.0 authorization server’s token endpoint when using the refresh token grant flow.
This specification is more promising in terms of potential adoption, but there are more details to iron out particularly in relation to using this from a browser, where an unexpected pop-out in the UX might be unacceptable.
OAuth 2.0 Demonstration of Proof-of-Possession at the Application Layer (DPoP)
The most recent specification to emerge from the sender-constrained token technologies set of specifications at the time of writing this is the Demonstration of Proof-of-Possession at the Application Layer (DPoP) .
Due to the lack of support for OAuth 2.0 Token Binding and undetermined user experience of mutual-TLS client authentication in user agents, neither mechanism can be used in practice today with most mainstream providers if an OAuth 2.0 client is a Single Page Application (SPA) running in a web browser.
This specification outlines an application-level sender-constraining for access and refreshes tokens that can be used in cases where the above two are not feasible. The main data structure introduced by this specification is a DPoP proof JWT. A client uses a DPoP proof JWT to prove the possession of a private key belonging to a certain public key. Roughly speaking, a DPoP proof is a signature over some data of the HTTP request to which it is attached to and a timestamp.
This mechanism allows for the detection of replay attacks with access and refreshes tokens.
Avoiding UI Redirections in SPAs
Sliding Sessions for SPAs
As discussed in the previous parts of the article, most of the standards for securing a refresh token in CSAs are still not yet mainstream. Therefore in cases where none of the standard solutions can be implemented, using long-lived refresh tokens may be discouraged by the security teams.
Luckily, there is an alternative to renew access tokens in SPAs without using refresh tokens or compromising user experience. If your OAuth 2.0 authorization server also supports OpenID Connect, which most popular OAuth 2.0 vendors support these days, you can leverage the presence of the logged-in session with the authorization server to request a new authorization code without any disruption to the UX via a hidden iframe and prompt parameter value set to ‘none’. This request can be made periodically at a configured interval, by having a count-down timer in the SPA, until the user is active in the SPA. This will return back an authorization code if the session exists in the OAuth 2.0 authorization server, or an error if the session has already ended in the OAuth 2.0 authorization server. The result can be passed into a callback function of the SPA window within which the iframe was loaded. Based on the result the SPA can decide, whether to proceed with the authorization code exchange and get a renewed access token or sign-out the user and sign-in again to get a new access token.
Although earlier on web views were used heavily for native mobile application login through front channel identity federation, more recently web views have been highly discouraged for login, due to their security properties. In typical web-view-based implementations of embedded user-agents, the host application can record every keystroke entered in the login form to capture usernames and passwords, automatically submit forms to bypass user consent, and copy session cookies and use them to perform authenticated actions as the user. Web views don’t provide the user any guarantee that they are actually entering their password on the service's website rather than a phishing site. Even if the app is trusted, making it possible to access the user's full credentials is unnecessary. This violates the principle of least privilege and increases the potential for attack.
As web views are opened in the context of an application, the session cookies are not shared among multiple application sessions. Therefore you also don’t get single sign-on behavior.
Authorization Server Agent on Mobile Device
The next step of the evolution for mobile application authentication and API authorization was to use an application in the mobile device, which acts as an agent for the OAuth 2.0 authorization service, provides single sign-on and manages API tokens.
Figure 1: OIDC authorization server agent for mobile native application
Native Applications Single Sign-On (NAPPS)
Though initially there were many proprietary vendor-specific implementations in the market, as time went by the OpenID Connect foundation formed a working group to develop a standard specification for this. The result of this was the Native Applications Single Sign-On (NAPPS) specification. However, with the more recent developments in mobile operating systems and the better user experience and security they can provide for in-app browsers, this specification would soon become obsolete.
RFC 8252 - OAuth 2.0 for Native Apps
OAuth 2.0 for Native Apps (RFC 8252) defines the most up-to-date recommendations for OAuth 2.0 for native applications (CSAs). Following are some of the important recommendations from this specification:
- Native applications must use OAuth 2.0 authorization code grant flow with PKCE.
- The authorization redirect from native apps must only be made through external user-agents, primarily the user's browser.
- The client type must be recorded during client registration to enable the server to determine the client type and process requests accordingly. Except when using per-instance secrets, native apps are classified as public clients.
- Public clients must not authenticate using shared secrets to the OAuth 2.0 token endpoint, as this doesn’t serve any real purpose. Client identification is done using the “client_id” request parameter.
- App-claimed "https" scheme redirect URIs should be used over other options where possible. identity of the destination app is guaranteed to the authorization server by the operating system.
- To mitigate cross-site request forgery over inter-app URI communication channels, public clients must use the OAuth 2.0 “state” parameter of the authorization request to include a high-entropy secure random number and reject any incoming authorization responses without a state value that matches a pending outgoing authorization request.
Figure 2: OIDC authorization code flow using system browser for mobile native applications
Web Controller for Native Apps
More recently, mobile operating system vendors like Apple and Google, have provided built-in support for web controllers with their respective operating systems, which provide the exact same functionality and security properties like the system browser, however with the kind of user experience you would get with web-views. Web controllers also provide cookie based single sign-on capability as with system browsers.
In iOS 9, Apple introduced SFSafariViewController. In iOS 11, they introduced SFAuthenticationSession which had benefits over SFSafariViwController. But it was later deprecated in iOS 12 and they introduced ASWebAuthenticationSession. Google introduced Chrome Custom Tabs in Chrome 45.
In this last part of the series, I have discussed the latest and upcoming standards following the sender-constrained token pattern aimed at solving the challenges in CSAs, and solution patterns being employed to improve CSA user experience.