I have swagger working on multiple microservices. When deploying to Azure we need to remove all together the option of swagger due to security best practices. Working with .net core 2.1 Looking for example of definitions.
4 Answers
First, what "security best practices"? There's nothing wrong with having your API documentation in production. That's actually kind of the whole point: clients should be able to look at the documentation so that they can properly use your API. If these microservices aren't exposed to be used by external clients, then it's even less of an issue, because no one outside can get to the service or the documentation, anyways. If the services are exposed, then they should also be requiring requests to be authorized, and the documentation itself can be locked down via the same mechanism.
Regardless, if you insist on removing this in production, your best bet is to never add it there in the first place. In other words, wrap all your Swagger setup in Startup.cs
with if (env.IsDevelopment())
or if you want it available in things like a staging environment: if (!env.IsProduction())
.

- 232,153
- 36
- 385
- 444
-
14I do not completely agree with this. You are correct to point out that the whole point of Swagger is to enable your clients to properly use your API. This becomes an issue of who you want to benefit here. I worked collaboratively with another company to build a product and we used Swagger as the commonly agreed API. In dev. But that doesn't mean we wanted any user on the Internet to use the API. In fact, we don't. We only want our mobile app to hit it. Nothing else. So, making Swagger publicly available in production in that case was a big "no way". Why risk it? – onefootswill Jan 22 '20 at 03:20
-
2Again, that's what authorization is for. It's either exposed to the Internet or not. – Chris Pratt Jan 22 '20 at 13:13
-
10I would suggest minimizing vectors of attack is a primary factor. If the general public has no business calling your API, they should not be given any information about it (via Swagger). As I said, it would be a case by case basis. If my API had a range of customers out there, then absolutely. But if it was just another dev team who helped develop an app (they do the app, I do the API), then I would not expose Swagger in production. There would not be much to gain from it. – onefootswill Jan 23 '20 at 00:56
-
I don't agree with this point for the reason most of the modern applications that are developed by developers are based on modern UI frameworks that communicate to API. In such cases, having the swagger enabled may cause the leak of solution design in the sense all the API and models will be visible to other people. But I agree if we have proper security then we can control the execution of API. – Sudhakar Chavali Apr 24 '21 at 20:39
-
Im actually having this same conversation in my head about whether swagger deserves to be hosted on the API service and i concluded 'no'. I use swagger to aid development, but then in the build pipeline, extract the swagger.yaml and host it on a server that points to the API and leave the API hosting itself. I figured I don't need the - however slight - added latency of loading swashbuckle objects in every API call. And it also allows me to manage `documentation` and `service` as individuals. – Kam May 27 '21 at 14:04
-
@onefootswill swagger is not your API. Swagger is documentation about your API. Either your API is secured or it's not. If it's not, and you don't want everyone to access it, then you need to add authorization to your API and that in itself has nothing to do with swagger. The authorization you add to your API, can also be used to protect the documentation. Nevertheless, people who can see your documentation whom you don't want it to see, are nothing with that info if your API itself is properly secured. – Creative Sep 28 '21 at 16:12
-
@Creative I get that. I will concede this point if you can show me one big enterprise that has a public Swagger page (& not including companies with public APIs, like Github). I'm sure their security team would nix it. Heck, where I work, we strip headers from every response such that it hides the server technology. If you sniff our responses using Fiddler, you will not see IIS, ASP.NET, Kestrel or any of those standard headers which give hackers an immediate head start. And Swagger - what a head start that would be! If you protect Swagger (& API private), there may be a case for exposing it. – onefootswill Sep 28 '21 at 23:22
If you're coming at this from .net core 3.1:
Assuming that the Startup
class' constructor copies the injected IConfiguration
to a local field called configuration
, then you can setup the Configure method like so:
public void configure(IApplicationBuilder app, IWebHostEnvironment env)
{
var applicationName = configuration.GetValue<string>("ApplicationName") ?? "MyApi";
var basePath = configuration.GetValue<string>("BasePath");
if (!string.IsNullOrEmpty(basePath))
app.UsePathBase(basePath);
if (!env.IsProduction())
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"{basePath}/swagger/v1/swagger.json",
$"{applicationName} {ReflectionUtils.GetAssemblyVersion<Program>()}");
});
}
}

- 2,093
- 1
- 18
- 22
First option, disabling it in Configure-method like:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// read from config
var config = (IConfiguration)app.ApplicationServices.GetService(typeof(IConfiguration));
enableSwagger = bool.Parse(config.GetValue<string>("EnableSwagger") ?? "false");
if (enableSwagger /*|| env.IsDevelopment()*/)
{
app.UseSwagger(o =>
{
o.RouteTemplate = "swagger/{documentName}/swagger.json";
});
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
}
}
or use:
if (env.IsDevelopment())
{
...
}
Second option is by completely removing all references and usings in code files by
#if USE_SWAGGER
using Microsoft.OpenApi.Models;
...
#endif
#if USE_SWAGGER
<some method>
...
#endif
add in .csproj:
<Choose>
<When Condition="$(DefineConstants.Contains('USE_SWAGGER'))">
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard3.1'">
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.6.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.6.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.6.3" />
</ItemGroup>
</When>
<Otherwise />
</Choose>
or
<Choose>
<When Condition="'$(Configuration)' == 'Debug'">
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard3.1'">
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.6.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.6.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.6.3" />
</ItemGroup>
</When>
<Otherwise />
</Choose>
Play around and you get profound!

- 1,894
- 21
- 25
You could also use [ApiExplorerSettings(IgnoreApi = true)]
in the controller classes you don't want to show in the documentation. This is an excludent action, meaning every class will be shown, except the ones marked with this attribute. (this is good when you want to make only a set of your APIs docs visible to a third-party consumer);

- 292
- 2
- 10