Subject: [OAUTH-WG] Recommended OpenId Connect Flow for SPA with Microservices

From: David Sautter <[email-masked]>
Date: Mon, 10 Jun 2019 10:06:12 +0200

Hello,

I'm trying to get my head around the current recommendation for using 
OpenId Connect with an SPA, that cannot directly communicate with a 
stateful backend for holding a session.

First I thought the Implicit Flow would be the way to go, then I noticed 
that it isn't recommended anymore because of the broad support of CORS 
nowadays, instead one shall use the Authorization Code Flow.

I think what confuses most people is, that the Authorization Code Flow 
can be implemented in two ways: With or without a backend service doing 
the token exchange for the frontend.

I understood the following: Using a backend service for doing the 
exchange of the auth code for the token with the IdP is considered more 
secure, because one cannot trust the browser to store the tokens 
securely. The drawback is that you will have to create your own session 
state between your backend and your frontend SPA (e.g. using a cookie).

I am in a scenario where I do not have "the one backend", but a bunch of 
microservices running on Kubernetes, so they could die and respawn at 
any given time. Do I need a API-Gateway for dealing with the 
Authorization Code Flow? Which ones would be recommended (standard 
compliant)?

Or is the alternative of handling the complete Authorization Code Flow + 
PKCE in the Browser considered a safe scenario?

I have been doing a lot of research but having trouble to clarify this. 
Thanks for your help!

Regards,

David

---
Diese E-Mail wurde von Avast Antivirus-Software auf Viren geprüft.
https://www.avast.com/antivirus

---

From: David Waite <[email-masked]>
Date: Tue, 11 Jun 2019 20:01:26 -0600

On Jun 10, 2019, at 2:06 AM, David Sautter <[email-masked]> wrote:

> I understood the following: Using a backend service for doing the exchange of the auth code for the token with the IdP is considered more secure, because one cannot trust the browser to store the tokens securely. The drawback is that you will have to create your own session state between your backend and your frontend SPA (e.g. using a cookie).

Security-wise your risks include both token exfiltration and arbitrary code execution. A proxying backend that holds the token might prevent XSS from exfiltrating the token, but by default does not limit the impact of someone driving the user’s browser directly instead.

There can certainly be other implementation/architectural benefits of this approach, however. You can limit actions taken by the SPA, provide a bridge to a remote domain for an API that doesn’t advertise CORS support, enforce rate limiting of APIs which may be charged upstream, and so on. You could also use this to enforce a common processing layer across user-facing components.

> I am in a scenario where I do not have "the one backend", but a bunch of microservices running on Kubernetes, so they could die and respawn at any given time. Do I need a API-Gateway for dealing with the Authorization Code Flow? Which ones would be recommended (standard compliant)?

The standards mostly focus on the protocols between client, AS/IDP, and protected resource. The products which say help you implement just the client don’t necessarily have standards to leverage between your code and theirs. Leveraging OIDC for web access is mostly pain free for traditional applications, but SPA applications are more like API clients and take some of the passive browser behaviors that you would leverage here (such as potentially redirecting for authentication on new page request).

> Or is the alternative of handling the complete Authorization Code Flow + PKCE in the Browser considered a safe scenario?

This is what we are recommending by default for https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps 

Content Security Policy is recommended for preventing XSS in that document. Subresource integrity isn’t explicitly called out, but is also invaluable.

To prevent exfiltration, the options are limited. 
- Token Binding will work, but only currently has support in Edge.
- Mutual TLS will work, but has a poor experience unless you are deploying alongside group policy.
- DPoP was written specifically for the browser use case (such as letting you use WebCrypto for non-exportable tokens). It is an early draft but has some initial implementations already.

You can also have risk and fraud analsyis against both. XSS would need to be detected by usage behavior, while Exfiltration could use environmental detection like address and user agent changes.
> 
> I have been doing a lot of research but having trouble to clarify this. Thanks for your help!

Hope this helps!

-DW