Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add token exchange ability into FusionAuth core #1943

Closed
1 of 4 tasks
mooreds opened this issue Oct 28, 2022 · 10 comments
Closed
1 of 4 tasks

Add token exchange ability into FusionAuth core #1943

mooreds opened this issue Oct 28, 2022 · 10 comments

Comments

@mooreds
Copy link
Collaborator

mooreds commented Oct 28, 2022

Add token exchange ability into FusionAuth core

Problem

This came up while discussing the react SDK.

In a traditional FusionAuth installation, if you are using the recommended Authorization Code grant, one has to have both a browser, which gets the authorization code, and a server side component, which receives the authorization code from the browser and holds the client id and client secret. The server side component then exchanges the client id, client secret and authorization code for an access token (and perhaps a refresh token). Those are then sent down to the client (or browser), or held in a session in the server side component.

FusionAuth gives you flexibility on where to store the token. For a non-zero set of use cases, we recommend setting an httponly secure cookie for the access token and sending it down, but doing so requires that additional server side component to be written and hosted someplace.

Solution

Add an application feature, which must be explicitly turned on, that adds a route to the FusionAuth server called /oauth-redirect. Let's assume FusionAuth is hosted at auth.example.com

When enabled, the authorized redirect url for the application would include the route https://auth.example.com/oauth-redirect. FusionAuth would, after an authentication, send the browser to https://auth.example.com/oauth-redirect with a state value of the clientid and the authorization code. The code in oauth-redirect would do the token exchange and send down the access token (and refresh token, if the offline_access scope was requested. The cookie would be an httponly, secure cookie, and the cookie domains would be set to .example.com.

You could also make the cookie domain configurable, as mentioned here: #1991

This would not work for everyone, but for many users would remove one more barrier to using FusionAuth.

I believe we already do this for the FusionAuth admin application (the /admin/login endpoint), so this would generalize and expose this functionality.

Documentation

Alternatives/workarounds

Fully implement the authorization code grant, write the server side code or use a library which does so.

Additional context

Came up while discussing SDK design and how Auth0's SDK works.

Community guidelines

All issues filed in this repository must abide by the FusionAuth community guidelines.

How to vote

Please give us a thumbs up or thumbs down as a reaction to help us prioritize this feature. Feel free to comment if you have a particular need or comment on how this feature should work.

Related: #1991

@robotdan
Copy link
Member

Not sure I understand the request. In this example FusionAuth is exchanging the auth code for the access token, and if this is the case, is there still value in using the authorization code grant?

@mooreds
Copy link
Collaborator Author

mooreds commented Oct 31, 2022

What other grant would be a better fit? Not implicit (since that delivers the token on the URL). Not the client credentials (because that requires the client to hold the client secret, which public clients cannot to).

What am I missing?

@robotdan
Copy link
Member

I suppose this is possible.

I'd have to think more about it. I think this effectively disables client verification (no client secret is necessary) and removes the possibility to utilize PKCE, or the state parameter and requires FusionAuth to operate in the same domain as your application.

We'd need to review each of these items and weigh the benefit to the end user and understand the risks as well.

I believe we already do this for the FusionAuth admin application (the /admin/login endpoint), so this would generalize and expose this functionality.

This is our own application, so we perform the token exchange the same as any other application. We just happen to have this application running in the same VM. Because we are own application, we can still utilize a client secret, PKCE, and the state parameter.

@voidmain
Copy link
Member

If all we are doing is a cookie drop and redirect, this might be a quick way to get cookies into the SPA. The flow would look like this:

  1. Redirect browser to FusionAuth
  2. User logs in
  3. FusionAuth redirects to itself at /cookie-drop
  4. FusionAuth completes OAuth token exchange
  5. FusionAuth redirects back to SPA at the same time it drops cookies

In step 5, I wonder if this would work with a cross domain cookie. We could test this out pretty easily and see how it interacts, but the /cookie-drop endpoint would essentially set the cookie domain to the domain of the SPA and then redirect back to the SPA.

Might be worth tinkering with to see if it helps with the SDKs we are writing.

@robotdan
Copy link
Member

robotdan commented Nov 2, 2022

I have a prototype that works, we just need to test in a SPA, but the cookies come back correctly. Maybe @mooreds can test in the EAP build.

@robotdan robotdan added this to Backlog in FusionAuth Issues via automation Nov 2, 2022
@robotdan robotdan self-assigned this Nov 2, 2022
@robotdan robotdan moved this from Backlog to Designing in FusionAuth Issues Nov 2, 2022
@robotdan robotdan added this to the 1.41.0 milestone Nov 2, 2022
@mooreds
Copy link
Collaborator Author

mooreds commented Nov 7, 2022

Talked with @robotdan about this. Seems like a great feature, but not high priority right now. If you, dear reader, think differently, please upvote.

@andrewpai
Copy link

New Solution

After internal discussion, here's the new proposed solution.

New Endpoints

We will create the following endpoints

  • Login endpoint
    • A GET endpoint that sets up PKCE and returns a redirect to the hosted login page
  • Token exchange endpoint
    • Called in the OAuth redirect sequence. This is a public endpoint, but is not exposed in the SDK. Rather, it is called via redirect after a user successfully authenticates form the hosted login page.
    • Sends auth cookies back to the browser (see below)
  • Logout endpoint
    • Redirects to /api/logout
    • Kills all auth cookies
  • Token refresh endpoint
    • If a valid refresh token exists in the refresh_token cookie, refreshes the access token and possibly the refresh token as well, based on the chosen token refresh policy.
    • Rewrites the access token cookie with an updated cookie expiration
    • Potentially rewrites the refresh_token cookie
    • Rewrites the token_expiration cookie with a new expiration time

Cookies

The token exchange endpoint will drop four cookies

  • access_token: a cookie containing the user's access token.
    • The expiration time of this cookie will mimic the expiration time of the access token
    • This is a secure, http-only cookie
  • refresh_token: a cookie containing the user's refresh token.
    • The expiration time of this cookie will mimic the expiration time of the refresh token
    • This is a secure, http-only cookie
  • id_token: a cookie containing the user's ID token.
    • The expiration time of this cookie will mimic the expiration time of the refresh token.
    • This is non-secure, non-httpOnly cookie that is visible to javascript
  • access_token_expiration: a cookie containing the access token's expiration time, used by javascript to know when to refresh a user's access token
    • This is non-secure, non-httpOnly cookie that is visible to javascript

@robotdan robotdan modified the milestones: 1.43.0, 1.44.0 Jan 30, 2023
@robotdan robotdan moved this from Designing to In progress in FusionAuth Issues Jan 31, 2023
@lyleschemmerling lyleschemmerling moved this from In progress to Code complete in FusionAuth Issues Feb 13, 2023
@lyleschemmerling
Copy link

FusionAuth Issues automation moved this from Code complete to Done Mar 27, 2023
@robotdan robotdan moved this from Done to Reviewer approved in FusionAuth Issues Apr 4, 2023
@robotdan robotdan added this to the 1.45.0 milestone Apr 4, 2023
@robotdan robotdan reopened this Apr 4, 2023
FusionAuth Issues automation moved this from Reviewer approved to In progress Apr 4, 2023
@robotdan robotdan moved this from In progress to Reviewer approved in FusionAuth Issues May 5, 2023
@mooreds
Copy link
Collaborator Author

mooreds commented May 19, 2023

Can we close this, @lyleschemmerling ? the hosted backend doc landed here: FusionAuth/fusionauth-site#2115

@robotdan
Copy link
Member

robotdan commented Jun 2, 2023

Closing. If anyone has outstanding tasks, please complete them or move to separate issues to track to closure.

@robotdan robotdan closed this as completed Jun 2, 2023
FusionAuth Issues automation moved this from Reviewer approved to Done Jun 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
FusionAuth Issues
  
Delivered
Development

No branches or pull requests

6 participants