okta / okta-oidc-js

okta-oidc-js
https://github.com/okta/okta-oidc-js
Other
395 stars 232 forks source link

CORS error while longing out using authService.logout("/") #861

Open mmoroppa opened 4 years ago

mmoroppa commented 4 years ago

I'm submitting this issue for the package(s):

I'm submitting a:

Current behavior

After updating okta-auth-js from v3.1.1 to v3.2.3 I get the following CORS error when I try to logout using authService.logout("/") or authService.logout("/")

Access to XMLHttpRequest at 'https://(host).oktapreview.com/oauth2/(server)/v1/revoke' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I have no other CORS error while signing in or fetching the profile.

Expected behavior

I should be able to logout without CORS errors

Minimal reproduction of the problem with instructions

Just try to authService.logout("/")

Environment

shuowu commented 4 years ago

@mmoroppa Thanks for reporting the issue. In the auth-js SDK, cors error is normally misleading, it mostly means underlying HTTP response is not in ok status. I'll also try to reproduce the issue to see the root cause.

shuowu commented 4 years ago

@mmoroppa I failed to reproduce the issue with the custom-signin sample (https://github.com/okta/samples-js-react/tree/master/custom-login) with the dependencies provided in this issue.

One suggestion I can think of is to clear the localStorage as stale data from other port may affect how the app works.

dougse commented 4 years ago

We are having a similar issue but with Angular - POSTS to the /revoke endpoint, returns a 401 but the body is {"error":"invalid_client","error_description":"Client authentication failed. Either the client or the client credentials are invalid."}

shuowu commented 4 years ago

@dougse looks like your app is revoking an invalid token. Can you please create a new issue with the reproduction details provided? Thanks

andredigenova commented 4 years ago

I'm also experiencing a similar issue. It appears to be a regression -- this was working fine in 3.0.2.

Looking in console it looks like the POST to https://{OKTADOMAIN}.okta-emea.com/oauth2/v1/revoke is returning a 403.

Calling authService.logout("/") a second time seems to work.

shuowu commented 4 years ago

@andredigenova I cannot reproduce your issue with @okta/okta-react@3.0.4 and @okta/okta-auth-js@3.2.2. I suspect you are running into a state where you are revoking with an invalid token. Also, 403 looks like you have a scope mismatch. I would recommend to clear your localStorage and try if you can still reproduce the issue.

shuowu commented 4 years ago

To correct here, revoke an invalid token will return 200 per https://developer.okta.com/docs/guides/revoke-tokens/overview/

mmoroppa commented 4 years ago

I still have the CORS issue, Do you have to have the Base url set up? Because it's optional (the url is in the trusted urls though)

Is there any specific configuration the auth server should have?

shuowu commented 4 years ago

@mmoroppa CORS issue may happen if you have an incorrect issuer, are you seeing the issue for logout only, or it also happens for login? Also, are you using the default auth server or a customized one?

shuowu commented 4 years ago

@mmoroppa not sure if this comment help: https://github.com/okta/okta-oidc-js/issues/753#issuecomment-673206476

mmoroppa commented 4 years ago

@shuowu It happens only on the logout. We are using a customize server, that's why I was wondering if there is some extra configuration that should be added. But the problem didn't happen before the update.

Regarding the comment you mentioned, I don't see what could be missing, because the client authentication is done on the same server when the user logs in. And if there is a miss configuration I'm guessing there should be a 40X answer instead of a CORS right?

shuowu commented 4 years ago

@mmoroppa Right, since CORS error is misleading in the SDKs sometime, just want to see if they are relevant. I suspect the change here (https://github.com/okta/okta-auth-js/commit/e020f5bda3dff3d9054c84e830f703f94b56db97#diff-7df4a2a48db526b0c861a4e70460d36eR296) caused your issue. As before the change, there is actually a bug in the SDK to just call /revoke endpoint with an empty token, but with the fix, a real token from storage seems to cause the CORS issue.

If you can reach out to our support team at developers@okta.com you can share details of your configuration and they can help us find out what is happening.

andredigenova commented 4 years ago

@shuowu cleared localStorage, logged in and hit logout and issue persists. It calls revoke which returns a 403. Looking at the request, I don't see any scope information in the request. It only contains token_type_hint and token in the payload and an authorization header.

If I call authService.logout a second time it behaves as expected but doesn't send a second revoke. It just clears local login state.

aarongranick-okta commented 4 years ago

@andredigenova Thanks for bringing this to our attention. We believe we have identified a flaw which is causing this CORS failure for token revoke. We are working on getting this issue fixed as quickly as possible. We will update this issue with further status as it becomes available. Thanks again.

aarongranick-okta commented 4 years ago

Internal ref: OKTA-323565

teja123r commented 4 years ago

I faced this issue when I passed incorrect values into <Security, once I fixed that this issue resolved.

andredigenova commented 4 years ago

Just an update -- I've tracked down my particular issue to problem on the client's network infrastructure that is causing the revoke request to become malformed. My issue is separate from the original poster's.

Sorry for the red herring!

ialsowalkdogs commented 4 years ago

Currently experiencing this in my application. On logout, I get the CORS error and the following error in my console:


"errorCode": undefined,
"errorId": undefined,
"errorLink": undefined,
"errorSummary": undefined,
"message": undefined,
"name": "AuthApiError",
"stack": "./node_modules/@okta/okta-react/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js/</<@https://localhost:3000/static/js/8.chunk.js:151055:19\nt@https://localhost:3000/static/js/8.chunk.js:149113:19\n./node_modules/@okta/okta-react/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js/</<@https://localhost:3000/static/js/8.chunk.js:149382:14\nt@https://localhost:3000/static/js/8.chunk.js:149113:19\n./node_modules/@okta/okta-react/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js/</<@https://localhost:3000/static/js/8.chunk.js:149916:14\nt@https://localhost:3000/static/js/8.chunk.js:149113:19\n./node_modules/@okta/okta-react/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js/</<@https://localhost:3000/static/js/8.chunk.js:151042:14\nt@https://localhost:3000/static/js/8.chunk.js:149113:19\n./node_modules/@okta/okta-react/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js/</<@https://localhost:3000/static/js/8.chunk.js:150443:14\nt@https://localhost:3000/static/js/8.chunk.js:149113:19\n./node_modules/@okta/okta-react/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js/</<@https://localhost:3000/static/js/8.chunk.js:149931:17\nt@https://localhost:3000/static/js/8.chunk.js:149113:19\n./node_modules/@okta/okta-react/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js/</<@https://localhost:3000/static/js/8.chunk.js:149132:18\n./node_modules/@okta/okta-react/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js/<@https://localhost:3000/static/js/8.chunk.js:149133:4\n./node_modules/@okta/okta-react/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js/<@https://localhost:3000/static/js/8.chunk.js:149103:28\n./node_modules/@okta/okta-react/node_modules/@okta/okta-auth-js/dist/okta-auth-js.min.js@https://localhost:3000/static/js/8.chunk.js:149104:2\n__webpack_require__@https://localhost:3000/static/js/bundle.js:790:30\nfn@https://localhost:3000/static/js/bundle.js:151:20\n./node_modules/@okta/okta-react/dist/AuthService.js@https://localhost:3000/static/js/8.chunk.js:148046:38\n__webpack_require__@https://localhost:3000/static/js/bundle.js:790:30\nfn@https://localhost:3000/static/js/bundle.js:151:20\n./node_modules/@okta/okta-react/dist/Security.js@https://localhost:3000/static/js/8.chunk.js:148879:39\n__webpack_require__@https://localhost:3000/static/js/bundle.js:790:30\nfn@https://localhost:3000/static/js/bundle.js:151:20\n./node_modules/@okta/okta-react/dist/index.js@https://localhost:3000/static/js/8.chunk.js:148955:36\n__webpack_require__@https://localhost:3000/static/js/bundle.js:790:30\nfn@https://localhost:3000/static/js/bundle.js:151:20\n./src/components/MainNav/HeaderNav/MainNav.tsx@https://localhost:3000/static/js/main.chunk.js:1471:93\n__webpack_require__@https://localhost:3000/static/js/bundle.js:790:30\nfn@https://localhost:3000/static/js/bundle.js:151:20\n./src/App.tsx@https://localhost:3000/static/js/main.chunk.js:215:114\n__webpack_require__@https://localhost:3000/static/js/bundle.js:790:30\nfn@https://localhost:3000/static/js/bundle.js:151:20\n./src/index.tsx@https://localhost:3000/static/js/main.chunk.js:1961:81\n__webpack_require__@https://localhost:3000/static/js/bundle.js:790:30\nfn@https://localhost:3000/static/js/bundle.js:151:20\n1@https://localhost:3000/static/js/main.chunk.js:2462:18\n__webpack_require__@https://localhost:3000/static/js/bundle.js:790:30\ncheckDeferredModules@https://localhost:3000/static/js/bundle.js:46:23\nwebpackJsonpCallback@https://localhost:3000/static/js/bundle.js:33:19\n@https://localhost:3000/static/js/main.chunk.js:1:61\n"}
sseidel16 commented 4 years ago

I'm also experiencing a similar issue. It appears to be a regression -- this was working fine in 3.0.2.

Looking in console it looks like the POST to https://{OKTADOMAIN}.okta-emea.com/oauth2/v1/revoke is returning a 403.

Calling authService.logout("/") a second time seems to work.

It seems indeed a regression. I have a repository working fine with 3.1.4 and another failing with 3.2.3.

swiftone commented 4 years ago

@sseidel16 - We remain unable to duplicate this issue. Can you (using the network dev tool in your browser):

You can reach out to our support team at developers@okta.com if you want to be able to share details outside of a public forum.

nryoung commented 4 years ago

@swiftone just to let you know that we were also seeing exactly what @sseidel16 was seeing. We upgrade to 3.2.3 and see the CORS error without changing our implementation in any way.

However, this morning, without making any changes, I am now able to successfully call authService.logout() with no issues, so I am wondering if something changed on the Okta side of things?

sseidel16 commented 4 years ago

@swiftone - The POST request does contain the correct auth header, but that never actually gets fired, because the preflight OPTIONS request (this request does not include the auth header since no preflight requests include it) does not come back with the proper response headers. @nryoung mine does not seem to be working.. Maybe I need to wait another day :P

sseidel16 commented 4 years ago

I think I found the root of my issue. The older version seems to be calling only GET /v1/logout, and never posting to /v1/revoke. The older version does not require adding anything to trusted origins to work, and I did not add all origins. The newer version making the POST seems to need to have it added to trusted origins. Once I add, it works fine. Is this expected behavior? @nryoung what do your trusted origins look like?

ahmet2mir commented 4 years ago

Hello,

I'm getting this issue too using okta-vue, only on logout.

From console I only see a first POST /oauth2/v1/revoke attemp directly blocked without any http status code

plus

Access to XMLHttpRequest at 'https://xxxxxxxxxx.okta-emea.com/oauth2/v1/revoke' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

But just after a successful HTTP OPTIONS /oauth2/v1/revoke call in code 200.

swiftone commented 4 years ago

@ahmet2mir - Thanks for the question, can you clarify a few parts for me:

a first POST /oauth2/v1/revoke attemp directly blocked without any http status code

Which browser? usually "blocked" without a status code results from a browser trying multiple identical calls, in which case the browser interrupts the earlier call, but permits the final call to attempt. Are you seeing multiple calls to /oauth2/v1/revoke? If so, what is the result for each?

just after a successful HTTP OPTIONS /oauth2/v1/revoke call in code 200.

Are there any CORS headers (example: Access-control-allow-origin) in the headers of the response to that OPTIONS call?

Lastly, do you have your domain (and port) listed in the Okta console with Trusted Origins, with the CORS box checked? See the guide that starts here: https://developer.okta.com/docs/guides/enable-cors/overview/ and click through to the following pages to see the steps to enable/confirm this setting.

swiftone commented 4 years ago

@ahmet2mir - one more follow-up: Are you using an Org auth server or a custom authorization server (/oauth2/default) as your issuer? It may be that using an org auth server encounters this problem.

(Note the confusing name choice where a custom authorization server may be called "default")

ahmet2mir commented 4 years ago

Damn, I completly missed this part, thank you @swiftone very much for your quick answer, it works! I just added the domain in trust origin (and I use an org server, without /default)

mfickett commented 3 years ago

I ran into this too, and fixed it by adding to trusted origins. I was confused because I'd listed my domain for my app (as both callback and logout URLs), but hadn't updated the trusted origin.

priyath commented 3 years ago

I get the CORS error if I manually trigger a POST /logout call using axios or fetch. However, if I trigger the /logout call via a form submit event, the CORS error does not show up.

This seems to be because the form submit event bypasses CORS checks through some header attributes, but the same headers are not supported through Axios or Fetch.

swiftone commented 3 years ago

@priyath - (Note: I'm no longer at Okta, so just answering as any other user)

fetch/axios will not send any cookies by default. For fetch() you will want to pass the option credentials: 'include', in the options object, and for axios you will want to pass the option withCredentials: true in the options object.

The CORS error is actually misleading - you are getting an error because of the missing cookie, and the error response from Okta doesn't include the CORS headers, so the browser shows a CORS error message. However, if you send the cookie, you don't get the error path on the Okta side, and the response will include the CORS headers, so the browser doesn't show the CORS error message, but CORS is not actually the problem.

Telling fetch/axios to send the cookies (with the above option) should fix things for you.

priyath commented 3 years ago

withCredentials

@swiftone Thank you for the response. Unfortunately, this did not work for me. I still get the cors on the browser's console when my client app requests the POST /logout endpoint registered by the OIDC middleware.

The event sequence is similar to this:

  1. axios logout request to http://localhost:3001/logout
  2. 302 redirect to the okta logout endpoint https://dev-xxxx.okta.com/oauth2/id/v1/logout?id_token_hint=
  3. okta logout endpoint OPTIONS 200
  4. okta logout endpoint GET results in the CORS error.
Access to XMLHttpRequest at 'https://dev-xxxxx.okta.com/oauth2/id/v1/logout?....' (redirected from 'http://localhost:3001/logout') from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

However, if I trigger the POST logout call via a form submit event everything works as expected because the CORS check is bypassed due to the Sec-Fetch-Mode: navigate header attribute. I cannot set the same header via axios or fetch.

I have updated the trusted origins on the okta server with the correct URLs.

For reference this is my initial axios call:

    axios({ method: 'post', url: '/logout', baseURL: 'http://localhost:3001',
      headers: {
         accept: 'application/json',
        'cache-control': 'no-cache',
        'content-type': 'application/x-www-form-urlencoded',
        'CSRF-Token': 'csrtf-token',
      },
      withCredentials: true,
    });