Reputation: 19183
I am using Swagger with ASP.NET Web API application. If I visit URL http://localhost:5000/swagger
Swagger list all the controllers and actions defined in these controllers. Lets say I have five controllers and each controller has one action. I want to create multiple views such that when
user says http://localhost:5000/swagger/v1
he gets to see all controllers
when user says http://localhost:5000/swagger/v2
he gets to see only one controller
when user says http://localhost:5000/swagger/v3
he gets to see only two controller
Basically I am trying to restrict access to controller via swagger. Based on user requirement, I will share specific URL with them.
Is it possible to achieve this with Swagger?
Upvotes: 1
Views: 394
Reputation: 2393
Yes, you can do exactly what you want.
You should do the following steps:
IDocumentFilter
and register it in SwaggerConfig.cs
as follows c.DocumentFilter<HideSwaggerEndpointsDocumentFilter>();
Example:
public class HideSwaggerEndpointsDocumentFilter : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
{
//enter code here
}
}
This filter is loaded once you load the swagger page. Inside it, you have control over each and every controller action. You can delete some actions based on any criteria decided by you.
foreach (var apiDescription in apiExplorer.ApiDescriptions)
{
var route = "/" + apiDescription.RelativePath.Substring(0, (apiDescription.RelativePath.IndexOf('?') != -1) ? apiDescription.RelativePath.IndexOf('?') : apiDescription.RelativePath.Length).TrimEnd('/');
var path = swaggerDoc.paths[route];
switch (apiDescription.HttpMethod.Method)
{
case "DELETE": path.delete = null; break;
case "GET": path.get = null; break;
case "HEAD": path.head = null; break;
case "OPTIONS": path.options = null; break;
case "PATCH": path.patch = null; break;
case "POST": path.post = null; break;
case "PUT": path.put = null; break;
default: throw new ArgumentOutOfRangeException("Method name not mapped to operation");
}
if (path.delete == null && path.get == null &&
path.head == null && path.options == null &&
path.patch == null && path.post == null && path.put == null)
{
swaggerDoc.paths.Remove(route);
}
}
Disclaimer:
If you put the above code in your DocumentFilter class it will delete all actions regardless of the given URL.
Inside the (foreach (var apiDescription in apiExplorer.ApiDescriptions)
) you can play and do your custom logic. You have access to HttpContext.Current
, so you can get the current URL.
If you don't want to delete the current action have something like this, before the swaggerDoc.paths.Remove(route);
.
bool forDelete = false; // your custom logic when it should be deleted
if (!forDelete)
{
return;
}
Hope this helps you.
Upvotes: 3