Open aldredb opened 4 years ago
The authorization server needs to be set up to allow CORS for this to work. However, even with an authorization server set up for CORS this sometimes fails because it unnecessarily adds "X-Requested-With" header to Token endpoint call, and that "upgrades" the request to require preflight. And as Token request is generally a simple request, some authorization servers don't handle preflight at all. The "X-Requested-With" header was added with this change: https://github.com/swagger-api/swagger-ui/commit/937c8f6208f3adf713b10a349a82a1b129bd0ffd
Unfortunately i don't have control over the authorization server..It's a managed service which I leveraged. Are there any workarounds that can be done?
@aldredb you can use requestInterceptor
to proxy requests through a CORS proxy. See the example here: https://github.com/swagger-api/swagger-ui/issues/1888#issuecomment-173179594
@hkosova What about laurynasr comment about removing the X-Requested-With header? This break CORS for us.
Looking at OIDC library on github neither appauth-js or oidc-client-js need preflight for this. It's all done with simple request.
The original problem that the X-Requested-With
header was added for (the browser does the wrong thing if you enter incorrect details) seems less of a problem than not being able to authenticate at all.
I'd argue that the header should be removed, or at least made configurable so that people who have issues with CORS can disable it.
In particular, PR #4934 concerns an oauth2 server that returns a header of WWW-Authenticate: Basic ...
- "basic" here seems incorrect; is a bug with the server rather than swagger-ui? If so, I think this change should be reversed, and maybe a test added that the request from authorizeRequest
complies with a simple request that won't trigger preflight.
@aldredb @BeCharem can you check whether the changes in this branch on my fork fix the problem for you?
https://github.com/SpoonMeiser/swagger-ui/tree/fix-cors-issue
Turns out that it doesn't fix the problem I'm having, but these changes add a test that the request is a "simple" request, so might be worth making a PR if it fixes someone's problem.
It fix the issue for us. No preflight and a successful call to the token endpoint.
It fix the issue for us. No preflight and a successful call to the token endpoint.
What exactly resolved the issue for you?
It fix the issue for us. No preflight and a successful call to the token endpoint.
What exactly resolved the issue for you?
Removing the "X-Requested-With": "XMLHttpRequest" Headers for the Token request as seen in SpoonMeiser commit.
It fix the issue for us. No preflight and a successful call to the token endpoint.
What exactly resolved the issue for you?
Removing the "X-Requested-With": "XMLHttpRequest" Headers for the Token request as seen in SpoonMeiser commit.
Ok. Thank you. How exactly can I reference @SpoonMeiser fork as a nuget package?
I don't know. I pulled his branch and tested locally to confirms the fix. I didn't go farther than that.
I don't know. I pulled his branch and tested locally to confirms the fix. I didn't go farther than that.
How exactly did you test locally? How did you reference a local version of swaggerUI without a nuget reference?
The reason I dont believe this is a solution is because I am encountering the exact same issue and have used a Chrome extension to remove the X-Requested-With header. Even after removing the header using the extension, it still has the same error message. Therefore, its hard for me to validate this is in fact the solution.
SwaggerUI have a standalone page in ./dist when you build it.
Steps I did to verify @SpoonMeiser branch:
ui.initOAuth({
clientId: "my-client-id",
usePkceWithAuthorizationCodeGrant: true
})
Only 1 GET request was done to the token endpoint. No pre-flight.
1 workaround I have found for me is to use Chrome Extension and force the response header Access-Control-Allow-Origin to be *
Even though I have a proxy that returns this same exact header, using a chrome extension to force modify the header strangely allows me to workaround the issue. For me, changing/modifying the X-Requested-With header did not resolve the issue.
1 workaround I have found for me is to use Chrome Extension and force the response header Access-Control-Allow-Origin to be *
Even though I have a proxy that returns this same exact header, using a chrome extension to force modify the header strangely allows me to workaround the issue. For me, changing/modifying the X-Requested-With header did not resolve the issue.
Our IdP reflect the origin, instead of replying with *. I don't know if this makes a difference.
access-control-allow-origin: https://localhost:44343
1 workaround I have found for me is to use Chrome Extension and force the response header Access-Control-Allow-Origin to be * Even though I have a proxy that returns this same exact header, using a chrome extension to force modify the header strangely allows me to workaround the issue. For me, changing/modifying the X-Requested-With header did not resolve the issue.
Our IdP reflect the origin, instead of replying with *. I don't know if this makes a difference.
access-control-allow-origin: https://localhost:44343
I dont believe it makes a difference since I can workaround the issue by using https://localhost:44386 or *
The million dollar question for me is : Why exactly would using a chrome plugin to set the value of access-control-allow-origin to the exact same value as the server response change the outcome of how the browser treats the response?
There is no difference whatsoever in the value returned from the server or from the plugin. They are the same value! Diff shown below
So in summary: I experienced the exact same issue that the author of this issue experienced. My temporary workaround ( certainly not permanent since API developer/customers are not going to want to download a plugin just for using an API) is to use a chrome plugin to override the value of the response header "access-control-allow-origin" to either "*" or "https://localhost:44343" , which is the exact same value returned from the server response. Therefore, I dont believe a proxy is necessarily the solution.
We are facing the same problem with an IdentityServer which does not support CORS for /conntect/token
requests.
Most swagger implementations (we are using NSwag
and Swashbuckle
) do however support injecting custom javascript code into the swagger startup page.
With this we were able to workaround the issue by using this code
window.fetch = function (fetch) {
return function () {
var req = arguments[1];
if(req.headers["X-Requested-With"]) {
delete req.headers["X-Requested-With"];
}
return fetch.apply(window, arguments);
};
}(window.fetch);
Hth someone else.
We are facing the same problem with an IdentityServer which does not support CORS for
/conntect/token
requests.Most swagger implementations (we are using
NSwag
andSwashbuckle
) do however support injecting custom javascript code into the swagger startup page.With this we were able to workaround the issue by using this code
window.fetch = function (fetch) { return function () { var req = arguments[1]; if(req.headers["X-Requested-With"]) { delete req.headers["X-Requested-With"]; } return fetch.apply(window, arguments); }; }(window.fetch);
Hth someone else.
This javascript solution does work, but what is the security risk of implementing this workaround?
Backreference, gitlab.com's oauth implementation has the same issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300077#note_975798994
Gitlab is not going to adjust CORS behaviour. Is there a chance to adjust it in the swagger-ui? :)
Any chance to get https://github.com/swagger-api/swagger-ui/pull/4934 reverted? This header breaks the integration with Dex IDP which I'm currently using 😒. While the above piece of JavaScript works just fine, it's a very ugly workaround.
Try this .NET package: AspNetCore.Proxy.
Add this code to your program.cs file after app.MapControllers().RequireAuthorization() and before app.Run()
app.UseProxies(proxies =>
{
proxies.Map("oauth", proxy => proxy.UseHttp(ConfigSettings.TokenUrl,
builder => builder.WithShouldAddForwardedHeaders(false)));
});
here is my flows parameter:
Flows = new OpenApiOAuthFlows()
{
ClientCredentials = new OpenApiOAuthFlow
{
TokenUrl = new Uri("/oauth", UriKind.Relative),
Scopes = new Dictionary<string, string>()
}
}
Any news on this? Still a problem
@lion7 ,
If you have control over you DEX Idp server, you can fix this by just adding this config under the web
section.
allowedHeaders: ['x-requested-with']
Thanks for the hint! This seems to be added in https://github.com/dexidp/dex/pull/3114 as a direct fix for this issue 😄
Q&A (please complete the following information)
Content & configuration
Example Swagger/OpenAPI definition:
Swagger-UI configuration options:
Describe the bug you're encountering
I used the
authorization_code
grant flow to receive my grant code, however, during token retrieval i received error:Auth ErrorTypeError: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
Screenshots