nextauthjs / next-auth

Authentication for the Web.
https://authjs.dev
ISC License
24.56k stars 3.45k forks source link

scope changes causing authentication to fail for EVEOnline provider #3760

Closed geraldm74 closed 2 years ago

geraldm74 commented 2 years ago

Description 🐜

Scope parameter in EVEOnlline provider is being overwritten with "openid"

The EVEOnline provider requires there to be NO scope parameter. However in the provider code it is specified as "publicData" but it's not even using that?

..., wellKnown: "https://login.eveonline.com/.well-known/oauth-authorization-server", authorization: { params: { scope: "publicData", }, },

However, when the login URL is constructed we get this:

url: 'https://login.eveonline.com/oauth/authorize?client_id=*redacted*&scope=openid&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fcallback%2Feveonline&nextauth=signin%2Ceveonline&state=GejPhUb_qWw8yj03eDsaDqmuN-tL1BLmXy3iRYW2Z-E

See in the URL that scope=openid .. does anyone know why this is happening? EVEOnline reports a authentication error saying the scope is invalid. Is there a way to completely remove the scope parameter from the login URL?

Is this a bug in your own project?

Yes

How to reproduce β˜•οΈ

Use the auth provider for EVEOnline. You'll need to get a developer API key which you can get from https://developers.eveonline.com/applications

Screenshots / Logs πŸ“½

image image

Environment πŸ–₯

System: OS: Windows 10 10.0.19043 CPU: (8) x64 Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
Memory: 4.19 GB / 15.93 GB Binaries: Node: 17.0.1 - E:\Program Files\nodejs\node.EXE npm: 8.1.2 - E:\Program Files\nodejs\npm.CMD Browsers: Chrome: 97.0.4692.99 Edge: Spartan (44.19041.1266.0), Chromium (97.0.1072.69) Internet Explorer: 11.0.19041.1202 npmPackages: next: ^12.0.9 => 12.0.9 next-auth: ^4.0.0-beta.7 => 4.0.0-beta.7 react: 17.0.2 => 17.0.2

Contributing πŸ™ŒπŸ½

Yes, I am willing to help solve this bug in a PR

geraldm74 commented 2 years ago

The last time the EVEOnline provider successfully worked was in next-auth release v4.0.0

geraldm74 commented 2 years ago

Update:

Changing the EVE Online application type from Authentication Only to Authentication & API Access and adding the publicData scope, it now successfully redirects you to the EVE Online login screen.

However I am now receiving a OAUTH_CALLBACK_ERROR saying the id_token is not present in TokenSet?

image

It seems that EVE Online does not return an id_token which next-auth is expecting?

When you get and use the code returned to get the access token, you get a response that looks like this from EVE Online:

{"access_token":"jZOzkRtA8B...LQJg2","token_type":"Bearer","expires_in":1199,"refresh_token":"RGuc...w1"}

Could it be that Next-Auth is expecting id_token and not access_token ?

geraldm74 commented 2 years ago

Update:

Interesting enough the access_token returned is a JWT token ... the payload data in the token includes the following:

{ "scp": "publicData", "jti": "f13e056c-6e4b-4f3b-bef9-2af9fb86ab48", "kid": "JWT-Signature-Key", "sub": "CHARACTER:EVE:character ID", "azp": "640d8f12cdba4dad941fbea400a5cd7b", "tenant": "tranquility", "tier": "live", "region": "world", "name": "character name", "owner": "owner", "exp": 1643528344, "iat": 1643527144, "iss": "login.eveonline.com" }

So to get the returned user data for NextAuth. All we need is the access_token as it contains the character name and character id which is all we need.

So the flow should be: 1) SSO to login.eveonline.com 2) Exchange code for access_token (JWT), token_expiry, token_refresh 3) Verify access_token (JWT) via https://login.eveonline.com/oauth/jwks 4) Extract user data from access_token (JWT).

Would the above be easy to implement with NextAuth?

geraldm74 commented 2 years ago

Update:

Adding the following code to the EVEOnline Provider options fixed the id_token problem:

token: { async request({ client, provider, params, checks }) { const tokens = await client.oauthCallback( provider.callbackUrl, params, checks ) tokens.id_token = tokens.access_token return { tokens } }, }

The OAuth profile data is returned correctly as follows:

[next-auth][debug][PROFILE_DATA] { OAuthProfile: { scp: 'publicData', jti: 'e8352ed6-6dab-4031-bc00-b4fa347ef756', kid: 'JWT-Signature-Key', sub: 'CHARACTER:EVE:----', azp: 'ab0f323397e04cc28718b0381965fa34', tenant: 'tranquility', tier: 'live', region: 'world', name: '----', owner: 'Oz7Q/sor0EvZ4VQwNCN35lk6uZc=', exp: 1643583849, iat: 1643582649, iss: 'login.eveonline.com' } }

However I then get a new error: [next-auth][error][OAUTH_PARSE_PROFILE_ERROR]

https://next-auth.js.org/errors#oauth_parse_profile_error Cannot read properties of undefined (reading 'toString') { error: { message: "Cannot read properties of undefined (reading 'toString')", stack: "TypeError: Cannot read properties of undefined (reading 'toString')\n" ....., name: 'TypeError' },

After this error I see the following:

[next-auth][debug][OAUTH_CALLBACK_RESPONSE] { profile: null, account: null, OAuthProfile: { scp: 'publicData', jti: 'e8352ed6-6dab-4031-bc00-b4fa347ef756', kid: 'JWT-Signature-Key', sub: 'CHARACTER:EVE:----', azp: 'ab0f323397e04cc28718b0381965fa34', tenant: 'tranquility', tier: 'live', region: 'world', name: '----', owner: 'Oz7Q/sor0EvZ4VQwNCN35lk6uZc=', exp: 1643583849, iat: 1643582649, iss: 'login.eveonline.com' } }

I'm assuming the undefined error message is to do with profile and account being null? Does anyone know why this is?

brownoxford commented 2 years ago

The Eve login endpoint does not return an id_token, so the eve configuration should be specifying idToken:false instead of true. This will lead to the login process trying to get at the userinfo_endpoint to look up user information, but the configured wellKnown of https://login.eveonline.com/.well-known/oauth-authorization-server does not provide that either.

The solution is to copy the EVEOnline configuration to your local code, set idToken to false, remove wellKnown, and manually specify authorization, token and userinfo.