auth0 / auth0-flutter

Auth0 SDK for Flutter
https://pub.dev/documentation/auth0_flutter/latest/
Apache License 2.0
57 stars 37 forks source link

loginWithRedriect with audience set returns wrong access token #360

Closed djkingCanada closed 7 months ago

djkingCanada commented 7 months ago

Checklist

Description

Added audience to login with redirect, in the chrome network tab I can see two calls to ouath/token end point. The first returns a valid JWT with the audience property, the second returns a blob. It is the second token that is returned by credentials.accessToken

This is either a bug or the audience parameter needs much better documentation.

Reproduction

In the flutter sample app, add the audience param to loginWithRedirect auth0Web.loginWithRedirect(redirectUrl: 'http://localhost:3000', audience: 'api identifier');

Add code to look at the access token returned by credentials.

Launch in a chrome web debug session, inspect the page when the login button comes up.
You will see two token exchange calls - first returns the expected JWT with the audience property and a valid signature, the second returns an arbitrarily token. The token returned by credentials.accessToken matches the second token, not the first.

Additional context

No response

auth0_flutter version

1.2.0

Flutter version

3.13.6

Platform

Web

Platform version(s)

No response

djkingCanada commented 7 months ago

Issue appears to be in Auth0Web.onLoad

if (await hasValidCredentials()) { return credentials(); }

calling credentials() without the audience param being set means that getTokenSilently will make the second token request without the audience parameter and that token is what is returned with the credentials.

Using a local copy of the SDK I set the audience param to my API Identifier and things worked as expected.

So when the audience param is set in loginWithRedirect we need to persist it in a way that onload can find it and pass it to the the credentials method. Would local storage be a good place for that?

djkingCanada commented 7 months ago

Just to confirm the Auth0Client.ts getTokenSilently looks up the token by audience

 const entry = await this._getEntryFromCache({
        scope: getTokenOptions.authorizationParams.scope,
        audience: getTokenOptions.authorizationParams.audience || 'default',
        clientId: this.options.clientId
      });

so not passing the audience means it doesn't find it and does the second incorrect exchange,

frederikprijck commented 7 months ago

Hey @djkingCanada, would it work if you set the audience when calling onLoad? Doing so should avoid the need to pass it for both loginWithRedirect and getTokenSilently.

I maintain Auth0-SPA-JS, and from an Auth0-SPA-JS point of view, the behavior you are seeing is expected when you do what you do. If you do not want that you should either:

We won't be adding any mechanism to remember the audience after calling login as the behavior is as designed, if you want that pass then to onLoad. You can always override them explicitly whenever needed on any other calls.

djkingCanada commented 7 months ago

@frederikprijck the sample app points to 1.2 of the frame work, and audience isn't option until after that, so we should probably update the sample app. So far I haven't been able to get the sample app to work 1.4, I'll see if I can find a version that will run and let me set the audience in onLoad, I'll try to find a version that will run the sample app and have audience as a parameter in onLoad and let you know.

Where in the documentation is this expected behavior documented? Do I have to specify the audience in both onLoad and loginWithRedirect?

frederikprijck commented 7 months ago

Do I have to specify the audience in both onLoad and loginWithRedirect?

No. If you specify it in onLoad, it can be omitted in loginWithRedirect.

So far I haven't been able to get the sample app to work 1.4

Unfortunately, 1.4 is a broken release, and we will follow up with a fix ASAP. Try 1.3.1 for now.

djkingCanada commented 7 months ago

@frederikprijck 1.3.1 does work. Setting audience in onLoad does the trick too. Thank you!

Can we improve the documentation on loginWithRedirect on the audience param? 'To have the audience specific access token returned by credentials set audience in onLoad' I'm not sure when you'd want to use the audience param in loginWithRedirect, if there is a good use case for it there then we should hilight that there.