Authentication and Authorisation with Auth0 and .NET 6

Getting Started

After signing up an account with Auth0 and created a tenant, we have to first create a client application on the dashboard. It represents the client or user agent (for example a React.js frontend application). Next we have to create an API on the dashboard as well. This will represent the .NET 6 resources. The RBAC has to be enabled and permissions have to be added to the token.

Authentication

Since we will be using the authorisation code flow, the first thing we need is to redirect the user to the Auth0 login page. The URL is usually

https://{{domain}}/authorize?audience={{the API identifier}}&scope=openid&response_type=code&client_id=s{{Client ID}}&redirect_uri={{Callback URL}}
curl --location --request POST 'https://{{domain}}' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'code={{the code we receive from callback page}}' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id={{Client ID}}' \
--data-urlencode 'redirect_uri={{Callback URL}}'
using Microsoft.AspNetCore.Authentication.JwtBearer; //install this package if it is not in the projectbuilder.Services
.AddAuthentication(configureOptions =>
{
configureOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
configureOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(configureOptions =>
{
configureOptions.Authority = {{Auth0 domain}};
configureOptions.Audience = {{the API identifier}};
configureOptions.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
NameClaimType = ClaimTypes.NameIdentifier
};
});
//... other code hereapp.UseAuthentication();
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
//... your other code here
}

Authorisation

Authorisation tells the API resources what a user can or cannot do. We can add permission information to a user on Auth0. First, add a custom permission named “read” in the “Permissions” tab in the API resource that we created earlier. Then, add the permission to the a user under the “User Management” page.

builder.Services.AddAuthorization(configure =>
{
configure.AddPolicy("read", policy => policy.Requirements.Add(new HasPermissionRequirement("read", "{{Auth0 domain}}")));
});
//... other code here//after app.UseAuthentication();
app.UseAuthorization();
public class HasPermissionHandler: AuthorizationHandler<HasPermissionRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasPermissionRequirement requirement)
{
var user = context.User.FindFirst(ClaimTypes.NameIdentifier);
if (user == null || string.IsNullOrWhiteSpace(user.Value)) return Task.CompletedTask;
if (!context.User.HasClaim(c => c.Type == "permissions")) return Task.CompletedTask; if (!context.User.HasClaim(c => c.Issuer == requirement.Issuer)) return Task.CompletedTask; var permissions = context.User.FindAll(c => c.Type == "permissions" && c.Issuer == requirement.Issuer).Select(c => c.Value); if (permissions(s => s == requirement.Permission)) context.Succeed(requirement); return Task.CompletedTask;
}
}
public class HasPermissionRequirement: IAuthorizationRequirement
{
public string Issuer { get; set; }
public string Permission { get; set; }
public HasPermissionRequirement(string permission, string issuer)
{
Permission = permission ?? throw new ArgumentNullException(nameof(permission));
Issuer = issuer ?? throw new ArgumentNullException(nameof(issuer));
}
}
[Authorize("read")]
[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
//... your other code here
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Teng Wei Song

Teng Wei Song

My journey as a self-taught developer. Feel free to drop by my online profile at tengweisong.com as well!