Securing swagger ui in production in ASP.Net Core-Part 2
In my previous article https://medium.com/@niteshsinghal85/securing-swagger-in-production-92d0a045a5, we had discussed about how we can secure swagger ui with basic authentication.
Securing with OAuth 2.0 and OpenIdConnect
With growing usage of OAuth and OpenIdConnect for the application, it is very much possible that the application is using OAuth and OpenIDConnect for authentication and authorization, in that case we want to use the same mechanism for securing swagger ui also instead of basic authentication.
In this tutorial, I am going explore how OAuth and OpenIDConnect be used for securing swagger ui.
Let’s start by making changes in our existing solution which we created in previous article.
Add a class called “SwaggerOAuthMiddleware” and add the following code
public class SwaggerOAuthMiddleware
{
private readonly RequestDelegate next;
public SwaggerOAuthMiddleware(RequestDelegate next)
{
this.next = next;
} public async Task InvokeAsync(HttpContext context)
{
if (IsSwaggerUI(context.Request.Path))
{
// if user is not authenticated
if (!context.User.Identity.IsAuthenticated)
{
await context.ChallengeAsync();
return;
}
}
await next.Invoke(context);
} public bool IsSwaggerUI(PathString pathString)
{
return pathString.StartsWithSegments("/swagger");
}
}
Add the following code in ConfigureServices method in startup.cs
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies"
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = Configuration["jwt:Authority"];
options.ClientId = Configuration["jwt:Audience"];
options.ResponseType = "code";
options.Prompt = "login";
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
});
modify the existing extension method to use SwaggerOAuthMiddleware
public static IApplicationBuilder UseSwaggerAuthorized(this IApplicationBuilder builder)
{
return builder.UseMiddleware<SwaggerOAuthMiddleware>();
}
Modify Configure method like below
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...app.UseAuthentication();
app.UseSwaggerAuthorized();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "SecureSwagger v1"));
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthorization();...
}
IdentityProvider
we need an identity provider to test our application. I am using KeyCloak as identity provider for demo but any other Identity provider can be also be used.
I have locally running docker version of KeyCloak. Follow the link to know more about how keycloak can be run locally as docker container.
Demo
I have created a user called “demo” in KeyCloak.
with all these changes we are ready to run our application.
Hit F5 to run the application.
as soon as application is starting swagger ui, it is redirected to login page.
we will login with our newly created user “demo”. once you login successfully it will redirect back to swagger ui.
Role Based Access
we can enhance further by restricting only to user in certain role.
for demo I have created a role called “devteam” and assign to our user “demo”.
Add the following code in SwaggerOAuthMiddleware.cs
if (!context.User.HasClaim("role", "devteam"))
{
await context.ChallengeAsync();
return;
}
with this change only user with role “devteam” is able to access the swagger ui.
Tell me your thoughts below in comment section..!