I have a react SPA and a .NET API, where the user will login using AD FS. I am exchanging auth code for token in the backend (using client secret as well), but sending back a cookie to the SPA. The flow goes like this:
- User opens SPA, gets redirected to the sign in page /oauth/authorize from AD FS. Generate code verifier + state.
- User signs in and is redirected back to the frontend.
- Frontend checks URL for auth code + state, verifies and calls the backend /api/authenticate, with the auth code + the code verifier.
- Backend calls the /oauth/token endpoint with auth code, code verifier and the client secret (stored only in backend) and is returned the token. Place this in memory, but sign the user in with cookies.
- SPA sends all requests to the API with cookies, no tokens in the browser.
This currently works, however, I am unsure of if I even need step 3, to redirect the user back to the frontend end only to call the backend again.
Can't I just use response_mode=form_post here? So that when the user has signed in at AD, the browser posts the auth code to the backend, and the backend exchanges that for the token, signs the user in with cookies and redirects back to the frontend?
Isn't this safer than having the auth code in the frontend?
Am I missing something here or is this not even possible? Just started reading up on OAuth and OIDC. Can get confusing at times..
Either can work and be considered secure, but here are some related factors when choosing.
SECURITY
Some people prefer the form post response mode, so that authorization codes do not end up in server logs or the browser history.
if using form post though, your BFF will set cookies in a redirect response. This may prevent the strongest SameSite=strict cookies from working.
These days a code flow should use both PKCE and a backend client credential, which ensure that a stolen authorization code cannot be abused to get tokens.
Some higher security options are explained in the JARM spec, which is supported by some authorization servers. This also supports form post.
OTHER FACTORS
The form post response mode still returns a browser / front-channel response, so does not improve efficiency. This response contains an auto form post.
The query response mode may make SPA usability control easier. Behaviors like storing locaton and page state before the OAuth redirect, then restoring it after processing the response.
There is also the potential for a minor usability issue with form post, where the user could get a form resubmission warning if they hit the back button after login.