Blazor with Auth0, using Swagger| OpenAPI
In this small series we’ll setup a Blazor Web Assemly Application which communicates with a C# REST API. We’ll protect the endpoints with Auth0 as Identity Provider based on Roles (RBAC).
Articles in this series:
- Blazor Authentication with Auth0
- Blazor Authorization with Auth0
- Blazor With Auth0, using the Management API
- Blazor with Auth0, using Swagger| OpenAPI (this one)
This article is the fourth one in the series, I highly recommend you to checkout the previous ones before continuing.
In the last article you’ve learned:
- Using the Management API to query all our users/roles stored in Auth0.
- Create a new Role using the Management API.
- Using the API Explorer to test certain endpoints of the Management API.
- Upgrade our API to a Machine to Machine (M2M) client to use the management API.
- Automatically re-use the access token leveraging Dependency Injection and Delegation Handlers
In this article we’ll cover:
- Authenticate Swagger or OpenAPI with Auth0 and call a ASP.NET REST API.
Use Case
- As a Developer I want to query the REST API using Auth0 authentication/authorization and Swagger or Open API.
The Final Result
Note, we did login before that’s why we do not need to provide credentials this time. But intially you’ll have to provide it.
Configuring Swagger
Swagger or OpenApi, helps us to make requests to our API without the need for a GUI or a client. If we want to add Auth0 to Swagger since we are doing authenticated requests. There are a few lines of code we need to provide.
In Server/Program.cs
removebuilder.Services.AddSwaggerGen()
and replace it with the contents seen below. Likewise replace the app.UseSwaggerUI().
using System.Security.Claims;
using Auth0Net.DependencyInjection;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Models; // 👈
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
// Remove the default builder.Services.AddSwaggerGen() and replace it with:
// 👇
builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
TokenUrl = new Uri($"{builder.Configuration["Auth0:Authority"]}/oauth/token"),
AuthorizationUrl = new Uri($"{builder.Configuration["Auth0:Authority"]}/authorize?audience={builder.Configuration["Auth0:Audience"]}"),
}
}
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "oauth2"
}
},
new string[] { "openid" }
}
});
});
// 👆
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = builder.Configuration["Auth0:Authority"];
options.Audience = builder.Configuration["Auth0:Audience"];
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = ClaimTypes.NameIdentifier
};
});
builder.Services.AddAuth0AuthenticationClient(config =>
{
config.Domain = builder.Configuration["Auth0:Authority"]!;
config.ClientId = builder.Configuration["Auth0:M2MClientId"];
config.ClientSecret = builder.Configuration["Auth0:M2MClientSecret"];
});
builder.Services.AddAuth0ManagementClient().AddManagementAccessToken();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
// 👇
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1.0");
options.OAuthClientId(builder.Configuration["Auth0:BlazorClientId"]);
options.OAuthClientSecret(builder.Configuration["Auth0:BlazorClientSecret"]);
});
// 👆
}
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers().RequireAuthorization();
app.MapFallbackToFile("index.html");
app.Run();
You’ll notice that we also need the BlazorClientId
andBlazorClientSecret.
In theory you could create a new “client” application and use that ClientId
and ClientSecret
but we’ll re-use the one from our Blazor Client. Navigate to the Auth0 Dashboard and find the Application of the client (Weather Station Client in our case) and copy the values in appsettings.json
of the server project. In the end the result will look like this:
{
"Auth0": {
"Authority": "https://<YOUR_AUTH0_DOMAIN>",
"ApiIdentifier": "<YOUR_API_IDENTIFIER>",
"M2MClientId": "<YOUR_M2M_CLIENT_ID>",
"M2MClientSecret": "<YOUR_M2M_CLIENT_SECRET>",
"BlazorClientId": "<YOUR_BLAZOR_CLIENT_ID>",
"BlazorClientSecret": "<YOUR_BLAZOR_CLIENT_SECRET>"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Done!
- Run your Server project and navigate to https://localhost:5001/swagger
- Click Authorise
- Do an authorised call!
Summary
Swagger is great especially if you do not have a client yet. Combining it with Auth0 is not that hard, but something you should “know”.
As always the source code is hosted on GitHub since we ❤ open source