auth0 / nextjs-auth0

Next.js SDK for signing in with Auth0
MIT License
2.08k stars 391 forks source link

Custom Scopes not being picked up from scope param. #665

Closed enjon-appstellar closed 2 years ago

enjon-appstellar commented 2 years ago

Describe the problem

I'm using the Organisation feature coupled with a SPA Application that ties with a certain Custom API I've created.

What normally happens is a user that is already registered to an Organization, logs in using that organization, and then they are redirected back to my Client-Side for which I'm authenticating my users. They should receive an access token when calling the getAccessToken() function provided from @auth0/nextjs-auth0 package, with the custom scopes I've set up in the [...auth0].js file, meant for the audience of my custom API.

Custom Scopes are not being picked up for the access token. I've set up the audience for my custom API which is created in the Auth0 dashboard. In the scopes param of authorizationParam during the execution of the handleLogin() function, I've added 'openid profile email ...my custom scopes...'. They were being picked up fine up until this week, and I have no idea why the custom scopes are not being picked up - it kinda seems like Auth0 is just ignoring them as they don't exist but I double-checked and they are created for my custom API.

What was the expected behavior?

Well, when we set up the correct audience and then add the desired scopes, when using the getAccessToken() function, I should've seen the scopes contained in that JWT, but only 'openid profile email' are being picked up.

Reproduction

import { handleAuth, handleLogin } from '@auth0/nextjs-auth0';`

export default handleAuth({
  async login(req, res) {
    try {
      await handleLogin(req, res, {
        authorizationParams: {
          audience: 'my-custom-api',
          scope: 'write:payment read:transaction read:transactions read:utilities write:beneficiaries read:account openid profile email'
        },
      });
    } catch (error) {
      res.status(error.status || 400).end(error.message);
    }
  }
});

image

Environment

adamjmcgrath commented 2 years ago

Hi @enjon-appstellar

This sounds like an issue with your tenant configuration rather than this SDK (you can confirm this by checking that the expected scopes are sent to /authorize in the query parameters)

Please, add your domain and clientId If you'd like me to check your tenant configuration.

enjon-appstellar commented 2 years ago

Hey @adamjmcgrath, the domain is https://swinto-lab.eu.auth0.com, but I'm not sure which clientId should I provide - is it the Application's clientId that you need?

enjon-appstellar commented 2 years ago

Also, I've checked the scopes being sent, and the only ones being sent are email and profile, tried to add one of my custom scopes, but it returned an error of invalid scope.

enjon-appstellar commented 2 years ago

@adamjmcgrath is there any way you can tell me what can I do to fix this issue? - it would be super helpful!

adamjmcgrath commented 2 years ago

@enjon-appstellar - could you share the full url of the request you are making to /authorize?

enjon-appstellar commented 2 years ago

Here you go @adamjmcgrath: https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?login_hint&response_type=code&redirect_uri=https%3A%2F%2Flogin.eu.auth0.com%2Flogin%2Fcallback&scope=email%20profile&state=Fe26.2**e7019060403756c10a7a9329a6eed1a3af88604f1488334b50c7c6b8571b2f75*GKjDwgHahZiSdUbl6_nkCQ*38F9xeTpsekSP65HIq-SlQ_J7ucRM1jW7HCNHhPmIuI**1aa0f22aa8e2bea44ed2aac31567e9dbea951780e988433e3693c3b2200c88c4*0O73oI3JG6_FC1cbQ8nDtBtv99dnu3PAqerrZXKJo98&client_id=104565000066-q7q63bouq2ct8gj73drmpu186amn6a3f.apps.googleusercontent.com&flowName=GeneralOAuthFlow

adamjmcgrath commented 2 years ago

Hi @enjon-appstellar - thanks for sharing that

This is your request to Google's login page, can you share the request to your-auth0-tenant.com/authorize which should happen immediately after your request to /api/auth/login

enjon-appstellar commented 2 years ago

Hey @adamjmcgrath, when I was reading the documentation it did mention that I don't have to implement those API calls myself, as that would be immediately implemented by Auth0.

Now, when I press login, I just redirect to the /api/auth/login route and Auth0 takes care of the process until the callback to my Next application happens. The first URL that gets hit is the URL to type in the organization, so I'm not able to show you the call to my-auth0-tenant.com/authorize. Am I maybe missing something?

adamjmcgrath commented 2 years ago

Hi @enjon-appstellar

When you visit /api/auth/login it will redirect you to /authorize (before redirecting you somewhere else) see

image

What I'm after is the query payload that's being sent to authorize

eg

image

I want to confirm that the expected scopes (write:payment, read:transaction, etc) are being sent to the Authorization Server, so I can rule out either the client or the server.

You could also just send me the HAR of the whole transaction (being careful not to share any secrets)

enjon-appstellar commented 2 years ago

Oh okay, here you go @adamjmcgrath - as I can see only openid, profile, and email permissions are being sent: https://swinto-lab.eu.auth0.com/authorize?client_id=8xgleDLUY43I6l7ERY9e4TiCSbOsVKjc&scope=openid%20profile%20email&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fapi%2Fauth%2Fcallback&audience=swinto-merchant-api&nonce=66w9xUdx-NCLQjISD3CJxZwLXBNV5NuMM5F0Q92wxqE&state=eyJyZXR1cm5UbyI6Ii8ifQ&code_challenge=OHOLhofle4-P8aEIB4BGG_8yjhZHmMUPeKXrdx7GJ3c&code_challenge_method=S256

adamjmcgrath commented 2 years ago

Ah, ok - thanks @enjon-appstellar, so the problem is with the Client.

Now if I update the sample app and change https://github.com/auth0/nextjs-auth0/blob/main/examples/basic-example/pages/api/auth/%5Bauth0%5D.ts to

import { handleAuth, handleLogin } from '@auth0/nextjs-auth0';`

export default handleAuth({
  async login(req, res) {
    try {
      await handleLogin(req, res, {
        authorizationParams: {
          audience: 'my-custom-api',
          scope: 'write:payment read:transaction read:transactions read:utilities write:beneficiaries read:account openid profile email'
        },
      });
    } catch (error) {
      res.status(error.status || 400).end(error.message);
    }
  }
});

Then visit /api/auth/login, I get redirected to https://adam-spa-test.us.auth0.com/authorize?client_id=GTENZRqsQrjJIa1mhPpylDpiRpoZAKmI&scope=write%3Apayment%20read%3Atransaction%20read%3Atransactions%20read%3Autilities%20write%3Abeneficiaries%20read%3Aaccount%20openid%20profile%20email&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fcallback&audience=my-custom-api&nonce=yT3m1bTEmpKgCRSsTx3pwNZFrmJGQlLysWxTfCeqOpY&state=eyJyZXR1cm5UbyI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCJ9&code_challenge=tWSHPVzm0OFYhgyJvL5WyzDBe_WbuJx29cTs63opVL0&code_challenge_method=S256

With the expected scope parameter:write:payment read:transaction read:transactions read:utilities write:beneficiaries read:account openid profile email

So I can't reproduce your issue with the information you've given me. I think in order to proceed you'll need to share a simple app that demonstrates the issue.

enjon-appstellar commented 2 years ago

Okay then, thanks for the assistance so far, I'll try and compare the example in https://github.com/auth0/nextjs-auth0/blob/main/examples/basic-example/pages/api/auth/%5Bauth0%5D.ts and see if there is something someone might've changed. I'll keep you updated. Thanks @adamjmcgrath.

enjon-appstellar commented 2 years ago

Hey @adamjmcgrath, so I tried using the Nextjs Auth0 example(https://github.com/vercel/next.js/tree/canary/examples/auth0), with my application and tenant env values and the call to /authorize includes my scopes as well, but when getting back the access token it comes back only with the profile, email, and openid. I even tried when getting the access_token sending the scopes as an array of strings but it didn't work.

I think there may be a problem with Auth0 setup, what do you think?

image image

enjon-appstellar commented 2 years ago

@adamjmcgrath I finally found what was wrong. The reason why it wasn't working was because in Organizations at members, I haven't assigned a role to my user containing those scopes/permissions. Now even though going to my user under Users left panel option, the user had all scopes/permission I was requesting, but when it comes to organizations, you must give the user a Role in the context of the organization for the Scopes to be picked up.

Thanks for the assistance, I highlighted some parts if anyone else stumbles on that issue.

Mmckelve45 commented 1 year ago

@enjon-appstellar you are an all-star my friend. I was stuck on this issue for 4 hours and couldn't figure out what was wrong. Organizations needs that explicit assignment... Thank you sir.

DLesage25 commented 1 year ago

@adamjmcgrath I finally found what was wrong. The reason why it wasn't working was because in Organizations at members, I haven't assigned a role to my user containing those scopes/permissions. Now even though going to my user under Users left panel option, the user had all scopes/permission I was requesting, but when it comes to organizations, you must give the user a Role in the context of the organization for the Scopes to be picked up.

Thanks for the assistance, I highlighted some parts if anyone else stumbles on that issue.

Dude you've saved me so much time. I wish the Auth0 documentation was clear abut this being a requisite when turning on the Organizations feature.

benevbright commented 1 year ago

@enjon-appstellar you deserve free beer or wine

smaspe commented 1 year ago

This is so insanely counter-intuitive...