Skip to content

Instantly share code, notes, and snippets.

@vertonghenb
Last active October 4, 2024 14:24
Show Gist options
  • Select an option

  • Save vertonghenb/17efe89c255cd7a010f27fc536d624b8 to your computer and use it in GitHub Desktop.

Select an option

Save vertonghenb/17efe89c255cd7a010f27fc536d624b8 to your computer and use it in GitHub Desktop.
Blazor with Auth0, using the Management API
{
"Auth0": {
"Authority": "https://<YOUR_AUTH0_DOMAIN>",
"ApiIdentifier": "<YOUR_API_IDENTIFIER>",
"M2MClientId": "<YOUR_M2M_CLIENT_ID>",
"M2MClientSecret": "YOUR_M2M_CLIENT_SECRET"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">Client</a>
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>
<div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="weather">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
</NavLink>
</div>
<AuthorizeView Roles="Administrator">
<div class="nav-item px-3">
<NavLink class="nav-link" href="add-weather">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Add Weather
</NavLink>
</div>
</AuthorizeView>
// ๐Ÿ‘‡
<AuthorizeView Roles="Administrator">
<div class="nav-item px-3">
<NavLink class="nav-link" href="users">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Users
</NavLink>
</div>
</AuthorizeView>
// ๐Ÿ‘†
</nav>
</div>
@code {
private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
using System.Security.Claims;
using Auth0Net.DependencyInjection;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
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();
builder.Services.AddSwaggerGen();
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();
}
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers().RequireAuthorization();
app.MapFallbackToFile("index.html");
app.Run();
using Auth0.ManagementApi;
using Auth0.ManagementApi.Models;
using Auth0.ManagementApi.Paging;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Shared;
namespace Server.Controllers;
[ApiController]
[Route("[controller]")]
[Authorize(Roles = "Administrator")]
public class UserController : ControllerBase
{
private readonly IManagementApiClient _managementApiClient;
public UserController(IManagementApiClient managementApiClient)
{
_managementApiClient = managementApiClient;
}
[HttpGet]
public async Task<IEnumerable<UserDto>> GetUsers()
{
var users = await _managementApiClient.Users.GetAllAsync(new GetUsersRequest(), new PaginationInfo());
return users.Select(x => new UserDto
{
Email = x.Email,
FirstName = x.FirstName,
LastName = x.LastName,
IsBlocked = x.Blocked ?? false,
});
}
}
namespace Shared;
public class UserDto
{
public required string Email { get; set; }
public required string FirstName { get; set; }
public required string LastName { get; set; }
public required bool IsBlocked { get; set; }
}
@page "/users"
@using Shared
@inject HttpClient Http
@attribute [Authorize(Roles = "Administrator")]
@if (users is null)
{
<p>Loading...</p>
}
else
{
<table class="table">
<thead>
<tr>
<th scope="col">Email</th>
<th scope="col">Firstname</th>
<th scope="col">Lastname</th>
<th scope="col">Blocked</th>
</tr>
</thead>
<tbody>
@foreach (var user in users)
{
<tr>
<th scope="row">@user.Email</th>
<td>@user.FirstName</td>
<td>@user.LastName</td>
<td>@user.IsBlocked</td>
</tr>
}
</tbody>
</table>
}
@code {
private IEnumerable<UserDto>? users;
protected override async Task OnInitializedAsync()
{
users = await Http.GetFromJsonAsync<UserDto[]>("user");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment