Guidance on Enabling oAuth 2.0 in Generated Swagger Docs

Response appreciated but not sure where to go from here. Are you saying the approach I showed above of using the built in oauth2 type wont work (in which case I need to scap it and use a different approach altogether - e.g. overwriting the popup page which still isn’t clear how to do - that link you provide doesnt explain how)? Or are you saying you don’t know how to get it to work because its beyond ServiceStack’s code base (in which case maybe someone else can help me work through the 4 issues I mentioned above)?

thanks.

For removing BasicAuth you can use ApiDeclarationFilter and SecurityDefinitions property. Just remove basic auth from SecurityDefinitions and you won’t see it in authorization page.Also you need to use OperationFilter and remove basic from Security property.

Do I correctly understand that you have swashbuckle configuration which works with this oauth server and Swagger UI? If it works can you share swashbuckle-generated swagger json? In this case we can say which filters you need to apply to get the same output for Swagger UI.

I have no idea if Swagger UI’s OAuth2 Type will work, we’ve never used it and wouldn’t work with any of our built-in OAuth/OAuth2 providers which Authenticate using OAuth Web flow and explicit AccessToken, not a bearer token that it seems to require.

I would consider taking the approach @xplicit mentions in this comment where you’d take the openapi.json generated by ServiceStack’s /openapi endpoint, customize it to a working configuration, then once you find a working configuration apply the changes using the OpenApiFeature filters, if you don’t know how to properly apply the changes send us a working openapi.json configuration and we’ll show you how to add it and add any missing properties if need be.

@mythz I wrote a custom provider (article shown above) that implements SS AuthProvider. Its working fine on the SS API when I call it from consuming applications, postman, etc. The issue here is just with Swagger. If we can get the built in oAuth2 type working that would be ideal (again, not just for me, but for many).

@xplicit here are the relevant sections from the json that swashbuckle generates:
{“swagger”:“2.0”,“info”:{“version”:“v1”,“title”:“My API Documentation”,“description”:""},“host”:“localhost:49717”,“schemes”:[“http”],“paths”:{"/mypath/{id}/attachments":{“post”:{“tags”:[“Attachment”],“operationId”:“Attachment_Post”,“consumes”:[“application/form-data”],“produces”:[“application/json”,“text/json”,“application/xml”,“text/xml”],“parameters”:[{“name”:“id”,“in”:“path”,“description”:“Guid”,“required”:true,“type”:“string”},{“name”:“file”,“in”:“formData”,“description”:“ZIP file. Files other that ‘.zip’ won’t be accepted. If archived file pathes are to long, zip file won’t be accepted.”,“required”:true,“type”:“file”}],“responses”:{“200”:{“description”:“OK”,“schema”:{“type”:“string”}}},“security”:[{“oauth2”:[“myapi”]}]}},"/loan/{id}":{“get”:{“tags”:[“Loan”],“operationId”:“Loan_Get”,“consumes”:[],“produces”:

and

},"securityDefinitions":{“oauth2”:{“type”:“oauth2”,“description”:“OAuth2 Implicit Grant”,“flow”:“implicit”,“authorizationUrl”:“https://AUTHURL/connect/authorize",“scopes”:{“myapi”:"My API”}}}}

unfortunately, neither of those show how to specify the client ID. :frowning:
I included the Swashbuckle config above that shows how it was specified in code.

all that said, with your tip @xplicit I was able to get rid of basic authentication on the popup which also somehow resolved the issue with scope not showing, as it shows now, so we killed 2 of the 4 issues! The major remaining issue is issue #3 - how to populate client_id=your-client-id which is what currently gets generated (with that dummy value) with our specific clientid…

That dummy value seems to be coming from index.html in swagger UI. In their readme, they seem to show how to configure it, but not sure how to tap into that with the OpenApi implementation. If I can’t , then I suppose we need to overwrite the index.html but I’m not sure how to do that since the Swagger implementation here is compiled code. If we can’t use the in-code configuration, how do I overwrite index.html with my own so it gets picked up by the Swagger compiler?

I suppose you already made changes for SecurityDefinitions according to swashbuckle json. If not, here is

new OpenApiFeature(ApiDeclarationFilter = api =>
{
    api.SecurityDefinitions.Add("oauth2", new OpenApiSecuritySchema
    {
        Type = "oauth2",
        Description = "OAuth2 Implicit Grant",
        Flow = "implicit",
        AuthorizationUrl = "https://AUTHURL/connect/authorize",
        Scopes = new Dictionary<string, string> { { "myapi", "My API" } }
    });
},
OperationFilter = (name, op) =>
{
    if (op.Security?.Count > 0)
    {
        op.Security.RemoveAll(d => d.ContainsKey("basic"));
        op.Security.Add(
            new Dictionary<string, List<string>>() { { "oauth2", new List<string> { "myapi" } } }
        );
    }
});

About index.html: you can create /swagger-ui folder in your web site root folder and place modified index.html there as described in ServiceStack.Api.OpenApi docs It will override default index.html which is bundled with OpenApiFeature

@xplicit thanks for the response. Are we saying there is no way to configure the clientID from code, like they show in the Readme?

specifically, they show:

ui.initOAuth({
clientId: “your-client-id”,
clientSecret: “your-client-secret-if-required”,
realm: “your-realms”,
appName: “your-app-name”,
scopeSeparator: " ",
additionalQueryStringParams: {test: “hello”}
})

You can do this, just follow instructions from previous comment:

index.html for modifcation can be downloaded from ServiceStack.Api.OpenApi sources or from Swagger UI sources

@xplicit We are talking past each other a bit - I will be more explicit (haha). There were two options I proposed in post 24 - the first, preferred option, is to configure the value of the clientID in code, the way they suggest in the readme I have linked twice and excerpted from in post 26. Please open the readme I linked and you will see exactly what I am referring to. I am asking if this is possible.

The second option, is to overwrite the index.html file, which would change the default value for clientid. This is not the intended usage by the Swagger folks - it would just be a hack-around. If the first option is not possible, then if you could provide guidance on where in my file structure, relative to the csproj file I would drop that index,.html, I would appreciate it. I can’t see any documentation on how to map the local project directory structure to the in memory structure that gets built at run-time.

thanks!

There has been multiple mentions of how to override Swagger Files (<- please read) by both myself and @xplicit, where his quoted comment is pretty straightforward, i’ll add emphasis:

Have you attempted to do this?

Every single static /swagger-ui file that’s embedded in OpenApiFeature.dll can be overridden in exactly the same way, these static files are copied directly from the distribution folder of the swagger-ui project - essentially everything in /swagger-ui is overridable.

The other option is to completely ignore the Swagger UI files in OpenApiFeature and just copy them directly from the swagger-ui GitHub project, it just needs a reference to an openapi.json url to generate is dynamic UI which you can get from the /openapi endpoint from your ServiceStack instance.

@mythz @xplicit I’m clearly having trouble communicating the first option as you guys keep talking about the second option which involves overwriting the index.html file. Can someone address what isn’t clear about the first option or at least say that it isn’t possible? Here it is again:

“You can configure OAuth2 authorization by calling initOAuth method with passed configs under the instance of SwaggerUIBundle default client_id and client_secret, realm, an application name appName, scopeSeparator, additionalQueryStringParams.

Can we do this? If you already said its not possible I apologize for asking again - I didnt see it.

@MSWCRB if you open index.html file you will see that this code is contained in index.html file. Change this file as you want and put index.html into /swagger-ui folder in the root of the web site.

Hmm. Please forget the index.html file for now. In the SwaggerUI documentation, it explains how to configure the client_id in code using the initOAuth method. Can this be done via the OpenAPI configuration? Again - this has nothing to do with index.html (I understand the default for these values are set there, but according to their docs, they should be set on the instance of SwaggerUIBundle in code).

I was asking two questions in my earlier posts and I think that was causing the confusion. I am trying only one question now…

Let’s assume you do not use OpenApi plugin at all. You use only Swagger UI which you get from github and json file with services specification. Do you know what you should change in Swagger UI according to their docs to call initOAuth method with your client_id? If you know what to do just make these changes and copy resulting files to /swagger-ui and you will get initOAuth working.

OpenApi plugin itself do nothing with javascript and html files, only one thing that it opens index.html file and replace default url with url to /openapi

So if you make the changes in index.html and put client_id in predefined values or will write your own javascript which will initialize this value in moment when you need then all of these will work with OpenApi plugin.

Just a note, in your post you reference SwaggerUIBundle from Swagger 3.0 docs, while OpenApi plugin uses version 2.2.10 of Swagger UI and you should use Swagger UI 2.2.10 docs.

initOAuth settings are defined here