Nswag: OAuth2 invalid redirection to localhost:3200 (SwaggerUi3)

Created on 25 Sep 2017  Â·  29Comments  Â·  Source: RicoSuter/NSwag

When you switch from .UseSwaggerUi() to .UseSwaggerUi3() and try to use OAuth 2.0 Authorization in the Swagger Ui, the redirection after signing in (to e.g. Azure AD) always wants to go to localhost:3000.

So:

app.UseSwaggerUi(typeof(Startup).GetTypeInfo().Assembly, new SwaggerUiSettings()
    {
        OAuth2Client = new OAuth2ClientSettings
        {
            ClientId = clientId,
            ClientSecret = clientSecret,
            AppName = "App",
                Realm = realm,
                AdditionalQueryStringParameters =
                {
                    { "resource", clientId }
                }
           },
          DocumentProcessors =
          {
              new SecurityDefinitionAppender("oauth2", new SwaggerSecurityScheme
              {
                   Type = SwaggerSecuritySchemeType.OAuth2,
                   Description = "DocCheck",
                   Flow = SwaggerOAuth2Flow.Implicit,
                   AuthorizationUrl = authorizationUrl,
                   TokenUrl = tokenUrl,
               })
           },
           OperationProcessors =
           {
               new OperationSecurityScopeProcessor("oauth2")
           },
           DefaultPropertyNameHandling = PropertyNameHandling.CamelCase,
    });

works correctly.
If you change it to SwaggerUi3 and SwaggerUi3Settings without changing anything else, you always get redirected to localhost:3000 after signing in. I guess its hardcoded somewhere?

done bug

Most helpful comment

I had the same issue using NSwag 11.18.6 on .NET Framework 4.6.1 web api.

The solution was set the Setting:

SwaggerUi3Settings.ServerUrl = "..."

@RSuter your fix from 19 Dec 2017 seems to work properly. Thanks!

All 29 comments

Have you checked the served HTML of Swagger UI 3? The auth settings are replaced here:

https://github.com/RSuter/NSwag/blob/master/src/NSwag.AspNetCore/SwaggerUi3/index.html#L99

Maybe we need more settings to make this work?

Can you try to host these files yourself (in your project):

https://github.com/RSuter/NSwag/tree/master/src/NSwag.AspNetCore/SwaggerUi3

and find a solution to this problem?
Replace index.html with the served index.html and modify it so that your scenario works...

As soon as we know how to fix this, we can implement this in NSwag...

Hitting this issue. ASP.NET Core apps are hosted behind a reverse proxy with IIS. Somehow the internal url is getting used as the redirect url for the oauth instead of the IIS specific address. Easiest solution would be to allow giving the redirect url in the C# OAuth2ClientSettings and using that when initializing the JS client.

Upon close inspection the wrong url was just a false positive on the identity server logs. The actual issue seems to be that the patch for the redirect is wrong. If my app is hosted at https://localhost/api/app then the redirect url is sent as https://localhost/oauth2-redirect.html. Is there somewhere option to set the base path?

After deepdive it seems that the problem is not with any reverse proxy thingy either.
It seems that the url is coming from here https://github.com/swagger-api/swagger-ui/blob/f22a6289345a3025650c687ab482a9e1a6369b07/swagger-config.yaml. How do I change it with the middlware?

Currently there are not many options in the Swagger UI 3 middleware... We need to add the missing options.

Any ETA?

Added the setting ServerUrl => check my commit. Is this how this should work?

Yes, that is my understanding of how it's suppose to work.

I'm not sure if the new ServerUrl property is required for anyone, but the default (empty setting) should make it use the current URL. Now you get redirect_uri=%2Fswagger%2Foauth2-redirect.html, which cannot work afaik, it must be an absolute URL.

If you use Oauth2/Redirect you also need to set the ServerUrl property... isnt it working if it is correctly set?

That requires knowing the URL beforehand. It's possible, but it's not very flexible, and I'd prefer not introducing such configuration in my code.

For example, locally the app might be running at https://localhost:44321/, so the desired redirect URL would be https://localhost:44321/swagger/oauth2-redirect.html

So, should we use window.location.origin when ServerUrl is not set?

That would cause problems when the site is configured as an application in IIS (e.g. http://myserver/MySite/swagger/index.html). The safest way would be to go from the current URL https://localhost:44321/swagger/index.html?url=/swagger/v1/swagger.json to https://localhost:44321/swagger/oauth2-redirect.html, but I'm not sure what the easiest JS method is to do that.

Something like this maybe:

window.location.origin + window.location.pathname.replace("index.html", "oauth2-redirect.html")

Do you think this would not work?

            html = html.Replace("{DocExpansion}", DocExpansion);
            html = html.Replace("{RedirectUrl}", string.IsNullOrEmpty(ServerUrl) ?
                "window.location.origin + \"" + SwaggerUiRoute + "/oauth2-redirect.html\"" :
                "\"" + ServerUrl + SwaggerUiRoute + "/oauth2-redirect.html\"");

Perhaps, it depends on what SwaggerUiRoute resolves to. If it handles a site being hosted at a location like http://myserver/MySite/swagger/index.html, then yes it would work.

To clarify, the scenario is the site one of the bottom two items in this screenshot:

image

I think in this case, you would set

MiddlewareBasePath = /MySite
SwaggerUiRoute = /swagger

and it should work...

Thanks, I'll give it a try tomorrow. Need to get an URL added to the valid redirect URLs by our OAuth team first.

Ok, but this change is not released yet...

I can reproduce this issue using Swashbuckle.AspNetCore.SwaggerUI 2.2.0 on AspNetCore app

Can we close this?

I have moved away from using it, so I couldn't say. Sorry.

John Morris
Sr. Software Architect
SoftPro


From: Rico Suter notifications@github.com
Sent: Tuesday, May 29, 2018 7:01 PM
To: RSuter/NSwag
Cc: Morris, John; Comment
Subject: Re: [RSuter/NSwag] OAuth2 invalid redirection to localhost:3200 (SwaggerUi3) (#961)

IMPORTANT NOTICE - This message sourced from an external mail server outside of the Company.

Can we close this?

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHubhttps://github.com/RSuter/NSwag/issues/961#issuecomment-392974748, or mute the threadhttps://github.com/notifications/unsubscribe-auth/Af_4UrhFen2z7kW3UCctP0oZi7sXuGLEks5t3dMtgaJpZM4PiWrS.


NOTICE: The information contained in this message is proprietary and/or confidential and may be privileged. If you are not the intended recipient of this communication, you are hereby notified to: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately.

I had the same issue using NSwag 11.18.6 on .NET Framework 4.6.1 web api.

The solution was set the Setting:

SwaggerUi3Settings.ServerUrl = "..."

@RSuter your fix from 19 Dec 2017 seems to work properly. Thanks!

The earlier reference to MiddlewareBasePath did not work for me. However the ServerUrl property does work. I know use this to correctly configure the url.
settings.ServerUrl = env.IsDevelopment() ? "https://localhost:44399" : "https://api.domain.com/v1";

I still have this issue using NSwag.AspNetCore 11.20.1.
I set the API Base URL to /api:
app.UsePathBase("/api");

I haven't set ServerUrl, because the API is published to multiple environments and I don't want to deal with absoute URLs in the code.

So the URL the API runs is https://domain.com/api/
Swagger is reachable on https://domain.com/api/swagger.

The generated oauth2 redirect URL is https://domain.com/swagger/oauth2-redirect.html but should be https://domain.com/api/swagger/oauth2-redirect.html.

So it seems the app.UsePathBase("/api"); is not incorporated into SwaggerUiRoute.

The suggested solution by @stijnherreman

window.location.origin + window.location.pathname.replace("index.html", "oauth2-redirect.html")

would work in this scenario and I think it should work in every case...

I've a similar problem.
On Development environment, the application runs on Kestrel.
Application runs on: http://localhost:5001.
Swagger runs on: http://localhost:5001/swagger.

On Production environment, the application runs on Kestrel _behind a Reverse Proxy_.
The domain is: dev.mydomain.com
The application has to run locally on the dev server on: http://myservername:5001
The application has to be reachable from outside on: http://dev.mydomain.com/control (thanks to the reverse proxy)
Swagger has to be reachable from outside on: http://dev.mydomain.com/control/swagger

So, there's the need to bind http://myservername:5001 to http://dev.mydomain.com/control. But actually the reverse proxy settings is not enough.

I see so many comments here about UsePathBase(), ServerUrl and so on... What are all the necessary settings and where are located?

Obviously, I want to avoid hard-coded strings and paths, because the application should be able to be moved to another server/environment without needing a recompilation.

I've created a new PR with a new setting: https://github.com/RSuter/NSwag/pull/1728
See #1717 (bottom) for more information

Closing issue as original problem is solved and discussions are now in this issue: #1717

Was this page helpful?
0 / 5 - 0 ratings