Search code examples
spring-securityoauth-2.0authorizationauth0spring-rest

How to pass user Security Principal to backend REST APIs with using Client Credentials Flow?


In my setup, there is a JavaScript app running on browser that is served by a Spring WebMVC application , which implements the backend for front end (BFF) pattern. The user access token is stored in the BFF server Session object. The BFF invokes REST APIs on the backed REST API servers using the client credentials flow . The user is authenticated by Auth0 iDP. We are also using Auth0 for providing credentials for client-credentials-flow. When the BFF starts up, it calls the Auth0 and gets access token to use with the REST API. Whenever the BFF makes an rest call into the REST Server, it passes the access token. Everything is working fine.

However, the REST APIs do not use Security Principal and hence we are not able to implement access control based on the security principal. I want to be able to use @PreAuthorize annotation to ensure that the entity that is being updated is owned by the Security principal. (assume every entity that I want to protect as a field "ownerid").

I want the BFF to pass some information about the authenticated user along with its access token. And I want to instantiate a Security principal for this execution context so that the @PreAuthorize annotations could use this information.


Solution

  • Your BFF should forward the user level token to the REST APIs. Doing so flows the user identity securely, and in a verifiable and auditable way.

    The API should process the token in the same way as currently. Various coding techniques could be used to pull out the principal, according to your preferences.

    If the BFF sends a separate token obtained by the client credentials flow, it would need to pass the user ID / subject in a separate plain HTTP header. This is not a good security practice, eg a man in the middle could potentially change it to a different user.

    If the API rejects the token, perhaps post back on the reason why. Eg maybe the API is rejecting the access token based on its audience claim value, or a required scope is missing.

    OAuth UI and API flows should be designed in an end-to-end manner, where the client is given scopes that provide access to one or more APIs, while flowing the user identity securely.

    The client credentials flow is best used for machine initiated end-to-end processes. One example might be a nightly batch job.