Imagine the following common scenario. I have a single-page web application (SPA) that receives all its data using RESTful APIs I wrote on the backend.
These APIs are available to third-parties as well, exactly as is. My single-page app is just another among millions using the APIs. A session is maintained in the background for the benefit of authentication and caching. The session persists through a cookie with a session-id.
To use the APIs, a user must authenticate. I need to support the big SSO method (OIDC/OAUTH2) for my application. Obviously, my APIs need to be usable by an integration software such as Dell Boomi or plain ol’ SSIS.
Now… let’s talk authentication and authorization flow. After days of reading everything I could on OAuth2 and OpenID, I imagine the following workflow. myapp.com is configured to SSO through Facebook (arbitrary):
- [Web Browser]:
GET /customer/1
> [API Server] - [API Server]:
Dunno you, chump. 302 redirect here, plz.
> [Browser] https://www.facebook.com/oauth/login?client_id=abcdef&state=12345 - [Browser]:
Username: lintlicker, password: iluvcats123
> [Facebook] - [Facebook]:
Yup, you're someone. 302 redirect here, plz.
> [Browser] https://www.myapp.com/oauth/imback?code=a1b2c3d&state=12345 - [Web Browser]:
json of the stuff from the url
> [API Server] - [API Server]:
Here's a code and client-id and client-secret
> [Facebook] - [Facebook]:
Here's a token to run Facebook APIs for this user
…………………………..
But, wait. I don’t want to run Facebook APIs. I just want to authenticate using Facebook, and then run my app’s APIs… Already you can see I misunderstood OAuth versus OIDC.
Okay, so then Facebook is the authenticator using OpenID. But what about OAuth for external use of my APIs?
Should my API server basically be forwarding the OAuth request from the browser/ requestor on to whoever the identity provider is? And then instead of a session-id in a cookie, I send back an access token that expires in, e.g., an hour, as well as a refresh token? Then the browser is responsible for re-upping the token?
Does that mean the browser or requestor has a client secret? Obviously not. So then does that mean I have to use/ support the depreciated implicit grant method?
What’s a good architecture here?
2
Answers
By using SSO your goal seems to provide social login behaviour. For this you do not need to rely on token issued by Facebook. What you can do is obtain user data from ID Token or by invoking user information exposing API of the identity provider (ex:- Facebook) and store them in one of your back-end. From there onward, you have the ability to maintain authenticated status either through your own token or a session.
About other integrations (API to API), for those integrations your back-end can issue tokens upon successful completion of an OAuth flow (ex:- client credential grant). And if such integration comes with an third party token (ex:- Facebook), then your back-end can allow a token exchange (plus user on-boarding, registration if required).
Downside of above approach is the requirement of your back-end to handle those requests. I would suggest to embed a lightweight identity provider if possible. This should give everything out of the box.!
I didn’t quite understand your request, but here is the answer from what I understood:
It’s not to the API to manage user authentication unless you’re in server-to-server mode, but it’s to the front-end to do that with the PKCE flow.
I don’t know the type of flow provided by Facebook, but if it’s PKCE, in this case your API does not have any role in the authentication process.
Then the API part his role is just to validate the token received from the client.