DEV Community

Robertino
Robertino

Posted on • Originally published at auth0.com

What's New in .NET 7 for Authentication and Authorization

Original post written by Andrea Chiarelli for Auth0 blog.

Let’s explore the new .NET 7 features for improving and simplifying authentication and authorization support in .NET applications.


The release of .NET 7 continues the simplification effort that began with .NET 5. Following this line, the new release provides .NET developers with a few features related to authentication and authorization that make .NET developers' lives a bit easier. Let's take a quick look at those features, which range from simplifications in authentication configuration to the addition of new authorization test tools, to improvements to Blazor's authentication support.

Default Authentication Scheme

When you configure authentication for your application, you need to register the authentication service through AddAuthentication(). For example, the following is the code needed to configure JwtBearer as the authentication scheme in an ASP.NET Core Web API:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
     .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
     {
         options.Authority = $"https://{builder.Configuration["Auth0:Domain"]}";
         options.TokenValidationParameters = 
           new Microsoft.IdentityModel.Tokens.TokenValidationParameters
         {
             ValidAudience = builder.Configuration["Auth0:Audience"],
             ValidIssuer = $"{builder.Configuration["Auth0:Domain"]}"
         };
     });
Enter fullscreen mode Exit fullscreen mode

Although you are defining just one authentication scheme (JwtBearerDefaults.AuthenticationScheme), the AddAuthentication() method requires that you specify the default scheme to use when it is not specified in your API endpoints (see this document for more details on multiple authentication schemes in ASP.NET Core).

Starting with .NET 7, the default scheme is no longer required when you define just one authentication scheme. It is automatically inferred by the framework. In practice, you can write the previous code as follows:

builder.Services.AddAuthentication() //👈 no default scheme specified
     .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
     {
         options.Authority = $"https://{builder.Configuration["Auth0:Domain"]}";
         options.TokenValidationParameters = 
           new Microsoft.IdentityModel.Tokens.TokenValidationParameters
         {
             ValidAudience = builder.Configuration["Auth0:Audience"],
             ValidIssuer = $"{builder.Configuration["Auth0:Domain"]}"
         };
     });
Enter fullscreen mode Exit fullscreen mode

In case you need to restore the old behavior for any reason, you can disable the new feature using the following statement:

AppContext.SetSwitch("Microsoft.AspNetCore.Authentication.SuppressAutoDefaultScheme", true);
Enter fullscreen mode Exit fullscreen mode

Simplified Configuration

One of the recurrent critiques of .NET authentication and authorization is its complexity (see this thread and this one, for example). Actually, .NET provides developers with an articulate system for managing authentication and authorization. This system is great for the flexibility it offers, but it may be hard for a beginner to digest all the details. It may be hard even for a more experienced developer who is not used to dealing with the identity features every day.

To overcome this issue, the .NET team started an initiative aiming at simplifying the authentication and authorization configuration. The .NET 7 release introduces the first step in this direction, bringing you a simplified approach to configure ASP.NET Core Web APIs authorization based on access tokens in JWT format.

Check out this article to learn how to protect your ASP.NET Core Web API.

If you ever had secured an ASP.NET Core Web API with Auth0, the following code should look familiar to you:

using Microsoft.AspNetCore.Authentication.JwtBearer;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
     .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
     {
         options.Authority = $"https://{builder.Configuration["Auth0:Domain"]}";
         options.TokenValidationParameters = 
           new Microsoft.IdentityModel.Tokens.TokenValidationParameters
         {
             ValidAudience = builder.Configuration["Auth0:Audience"],
             ValidIssuer = $"{builder.Configuration["Auth0:Domain"]}"
         };
     });

builder.Services.AddAuthorization();

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
Enter fullscreen mode Exit fullscreen mode

Now, you can directly rely on the built-in configuration system to define your Web API's authorization options. In fact, in addition to default authentication schemes, .NET 7 automatically loads the options to configure the authentication service from the new Authentication section of the appsettings.json configuration file. With this new feature, the code shown earlier becomes as follows:

using Microsoft.AspNetCore.Authentication.JwtBearer;

var builder = WebApplication.CreateBuilder(args);

builder.Authentication.AddJwtBearer(); //👈 new feature

builder.Services.AddAuthorization();

var app = builder.Build();
Enter fullscreen mode Exit fullscreen mode

All the configuration settings are moved to the appsetting.json file as follows:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  //👇 new section
  "Authentication": {
    "Schemes": {
      "Bearer": {
        "ValidAudiences": [ "YOUR_AUDIENCE" ],
        "ValidIssuer": "YOUR_AUTH0_DOMAIN"
      }
    }
  }
  //👆 new section
}
Enter fullscreen mode Exit fullscreen mode

The new Authentication section keeps the configuration settings for any authentication scheme supported by your application, although currently only the JwtBearer scheme is supported.

Notice that now you don't need anymore to call UseAuthentication() and UseAuthorization(). The framework takes care of automatically adding the required middleware to the request pipeline.

Authorization Policies for Specific Endpoints

ASP.NET Core allows you to specify policies to make more accurate authorization decisions based on the access token content or other advanced criteria. Usually, these policies are defined globally at the application level and attached to the endpoint definitions the policy applies to.

Take a look at this article to learn how to use policies to protect ASP.NET Core Web APIs, for example.

Defining policies globally is pretty good for reuse. However, sometimes you may need just a specific policy for one endpoint. In this case, you can specify your policy directly on the endpoint definition.

The following is an example of how you can use this new feature:

app.MapGet("/api/special-endpoint", () => "A special endpoint!")
    .RequireAuthorization(p => p.RequireClaim("scope", "api:special"));
Enter fullscreen mode Exit fullscreen mode

Read more...

Top comments (0)