1
votes

Alright, so I'm having a hard time understanding a proper flow here for my setup.

Goal

I want to have a proper SSO flow for my SPA app that can authenticate users into an API.

Context

I have a React application that is intended to use an Okta porta that offers both SAML (preferred) and OIDC for SSO flows. I've wrapped my static sources in a web server that serves them, and that server has a middleware that checks for cookies, and if one doesn't exist, I redirect to the IDP (Okta) for login. This all works fine for now.

Currently, my API sits on that same server, which I intend on moving to a separate server to scale independently of the website. My API must also allow other machine clients (services) to call into it, so I implemented a service account flow that uses client ID and secret as the authentication measure.

In general, my intended flow looks like this:

User navigates to my website (unauthorized) -> Web Server -> Redirect to IDP -> Assertion Callback flow -> Generate JWT session cookie -> Web Application makes API call -> API Server auth middleware validates cookie / bearer token.

The problem.

The details of how the JWT access token is generated is where I'm stuck. Currently, my webserver receives the SAML assertion and generates a JWT, which is not the same JWT claims logic as the service accounts (bleh). I'm thinking of implementing an Auth service instead to centralize the token generation flows.

For the Auth Service, I've looked into OAuth2.0 and it seems like just the right approach for what I need. With that said, I can't find much information on patterns to follow for SAML assertion -> OAuth2.0. I saw an IETF draft for saml2-bearer grant-type, but it seems dead in the water. I'm also unsure about the general consensus on custom implemented OAuth2.0 grant types.

What does a proper flow look like? I have a couple of scenarios in mind:

  1. SAML Service Provider within the same service as the Auth Service. On lack of SSO session, my application redirects to my Auth service, which then redirects to my IDP. The IDP calls my SP (the auth server) with the assertion, the auth service generates a token, then my auth service redirects back to the webserver with a cookie placed in the response headers.

  2. SAML SP as the webserver Since the webserver is the only system that needs to use the SSO, I could just keep the SAML flow within that process. Once my webserver receives the SAML assertion callback, my server makes a call to an endpoint service with the assertion claims, and then my auth service returns the access token in a JSON response.

  3. Something else, like OAuth2.0 authorization code flow with PKCE for the web application. Or OIDC instead of SAML for SSO.

1
I'm not posting this as an answer... Because it's not going to be good enough. SAML isn't the right choice without a dedicated Service Provider (which would be the mechanism that manages conversion from SAML to OAuth or OIDC). What you have at this point is an Authorization Server (Okta) and a Resource Server (your stuff). Based on what you've listed, I would recommend chasing the third option you listed.Andrew K.
I maintain an OSS project Osso that wraps SAML auth against IDPs (including Okta) in an OAuth 2.0 authorization code flow. I'm not sure it fits your needs exactly, but could be useful as prior art github.com/enterprise-oss/osso It allows an app to add Osso as an OAuth provider, Osso handles SAML, and then returns the user to your application with an authorization code which you can exchange for an access token. Where we fall short as a solution for you is that the access token is only useful for getting a profile for the user - we expect you to handle authorization yourself.sbauch

1 Answers

0
votes

OIDC sounds like the right choice for you as APIs are involved. OAuth is designed to secure APIs' compared to SAML which is built for enterprise SSO.

You can integrate your SPA with Okta using OIDC. Okta provides SDK's for varies platforms to make it easier for you to do so. You can find SDKs' here: https://developer.okta.com/code/angular/okta_angular_auth_js/

Once you get an ID token and Access token from Okta after OIDC flow, you can use the access token to access external API's. Your API resource server or the API gateway can validate the access token. Again Okta provides SDK's to verify access tokens: https://developer.okta.com/code/dotnet/jwt-validation/