Securing swagger ui in production in ASP.Net Core-Part 2

Nitesh Singhal
3 min readAug 13, 2021

--

Swagger + OAuth 2.0 logo

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.

KeyCloak’s Login page
Swagger UI after successful login

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”.

added new role in KeyCloak

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..!

--

--

Nitesh Singhal

Software architect, Exploring ASP.Net core and containerization technologies