Single Page Applications

Securing Single Page Apps using the OAuth2 Implicit Grant Flow

Use Case Description

Modern Single Page Applications are typically powered by a backend REST API, which needs to be secured against misuse. As the application lives entirely in the browser (user agent) of the end user, and does typically not have a server session, traditional approaches for this (server side sessions) are not desired.

In order to decouple the backend API and frontend application, an API Gateway can be put in place to implement the OAuth 2.0 Implicit Grant Flow, which is the recommended way of solving giving a "public" client (as opposed to a "confidential" client) access to an API.

 

Development Time Workflow

For development time, the following workflow is typical:

  1. The developer signs up for the API Portal and registers the single page application in the portal; the developer specifies exactly under which URL the SPA will be reachable from (tick the "OAuth 2.0 Redirect URI" check box for the application)
  2. By creating a subscription to the Backend API, the developer obtains client credentials for the single page application, a client ID and a client secret; for this use case, only the client ID is significant
  3. The developer incorporates the client ID into the single page application:
    • If the SPA does not have a valid access token (e.g. in the HTML5 local storage), redirect to the Authorization Server (the URL of which is stated on the API page in the API Portal), specifying which application is calling by passing on the client_id=... and grant_type=implicit in the redirect parameters
    • Expect to get called back being passed an access token in the fragment of the URL of your own application (e.g. `https://my.spa.com/#access_token=abc928987dffabe9273`)

For the OAuth2.0 Implicit Flow Grant, it is not necessary and actually "forbidden" to also incorporate the client secret into the single page app; in case the API also supports the client credentials flow, this would enable attackers to reverse engineer the app and extract the credentials. The client ID helps the authorization server to know exactly to which URL it will deliver the access token.

Runtime Workflow

To illustrate the runtime flow of such an authentication and authorization process using the OAuth 2.0 Implicit Flow Grant, see this picture:

Usually, the SPA will try to store an access token inside its local storage; in case there is none to use, or if it has expired, the SPA should redirect to the Authorization Server to get a new token. How the Authorization Server decides whether or not to issue a (new) token to the single page application is an implemnetation detail and inherently part of the business logic of your single page application.

The Authorization normally delegates finding the identity of the end user (authenticate the user) to an external Identity Provider, which can be most anything, e.g. a SAML SSO IdP, Google, Github or any other Provider which allows for integrations.

 

How do I implement this with wicked?

wicked.haufe.io supports the OAuth 2.0 Implicit Flow, even though not entirely out of the box: You will need to provide an Authorization Server on your own.

To illustrate how such Authorization Servers can be implemented, there are two sample projects assosicated with wicked which integrate with different Identity Providers:

  • The project wicked.auth-passport leverages the node.js PassportJS library to provide the following social logins:
    • Google (Plus) login
    • Github login
    • Facebook login, and
    • Twitter login
  • In wicked.auth-saml you will find an Authorization Server which can be used to integrate with SAML type Identity Providers; this Authorization Server will let you federate a SAML SSO session to an OAuth 2.0 Implicit Flow, which can be really useful if you need to integrate in Enterprise Scenarios.

Both sample projects will allow some parameterizing out of the box, but both do not provide any kind of additional authorization -- if the user was able to authenticate with the desired identity provider, this is considered enough to also be authorized.

For wicked.auth-saml, you will find a stub in authorize.js which shows where to put custom authorization code, in case you need or want that.


Back to top

© 2016-2017 Haufe-Lexware GmbH & Co. KG, www.haufe-lexware.com, www.haufe.de, www.lexware.de, www.haufe-akademie.de