You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today, configuring authentication/authorization for an ASP.NET Core application requires adding services and middleware at different stages of the app startup process. We've seen feedback that users find configuring authnz one of the hardest things about building APIs with ASP.NET Core.
Given authnz is regularly a cross-cutting, top-level concern of configuring an application, and very often the first thing someone wants to do after getting an API working, we should consider making it simpler to discover and configure.
Adding authentication to an app
Here's a minimally functional app at the point where it is ready to have authentication configured:
varbuilder=WebApplication.CreateBuilder(args);varapp=builder.Build();app.MapGet("/hello",()=>"Hello!");// Configure the following API to require the client be authenticatedapp.MapGet("/hello-protected",()=>"Hello, you are authorized to see this!");app.Run();
Adding auth today
To protect the second API today, services must be added, along with two middleware, and finally an authorization requirement defined on the API endpoint itself:
usingMicrosoft.AspNetCore.Authentication.JwtBearer;usingMicrosoft.AspNetCore.Authorization;varbuilder=WebApplication.CreateBuilder(args);// Add the authentication and authorization services for the desired authentication schemebuilder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(jwtConfig =>{jwtConfig.Authority="https://example.com";jwtConfig.TokenValidationParameters=new(){ValidAudience="MyAudience",ValidIssuer="https://example.com"};});builder.Services.AddAuthorization();varapp=builder.Build();// Add the authentication and authorization middlewareapp.UseAuthentication();app.UseAuthoriziation();app.MapGet("/hello",()=>"Hello!");// Add authorization configuration to the APIapp.MapGet("/hello-protected",()=>"Hello, you are authorized to see this!").RequireAuthorization();app.Run();
Every one of these changes must be applied in the correct phase of application startup (i.e. called on the right type and put on the right line) in order for the second API to be successfully protected so that only authenticated users can call it. This involved introducing the following concepts:
Importing namespaces
Adding services via the builder
Adding and configuring an authentication scheme using an options configuration delegate
Adding middleware that are order-dependent
Adding endpoint metadata
If access to the protected endpoint is to require more than simply the fact the client is authenticated, then a "policy" must be defined as part of the authorization services being registered in the DI container, and then referred to when adding the endpoint metadata:
usingMicrosoft.AspNetCore.Authentication.JwtBearer;usingMicrosoft.AspNetCore.Authorization;varbuilder=WebApplication.CreateBuilder(args);builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(jwtConfig =>{jwtConfig.Authority="https://example.com";jwtConfig.TokenValidationParameters=new(){ValidAudience="MyAudience",ValidIssuer="https://example.com"};});builder.Services.AddAuthorization(authzOptions =>{// Define the policy hereauthzOptions.AddPolicy("HasProtectedAccess", policyConfig =>{// Add requirements to satisfy this policypolicyConfig.RequireClaim("scope","myapi:protected-access");});});varapp=builder.Build();app.UseAuthentication();app.UseAuthoriziation();app.MapGet("/hello",()=>"Hello!");// Update the authorization configuration to the API to require the added policyapp.MapGet("/hello-protected",()=>"Hello, you are authorized to see this!").RequireAuthorization("HasProtectedAccess");app.Run();
While very flexible, this process can seem overly complex for something that many folks consider a simple scenario.
Adding auth via new simplified process
The general idea is to explore promoting authentication and authorization to be more of a first-class concept of WebApplicationBuilder, as is already the case for logging and configuration, building atop of the existing authentication and authorization primitives in ASP.NET Core.
Some proposals to explore:
Adding top level members to WebApplicationBuilder to enable configuration of authentication and authorization
Automatically adding the authentication and authorization middleware to the application request pipeline when authentication is configured via WebApplicationBuilder
Given our original example app that's ready for configuring authnz in, consider the following:
varbuilder=WebApplication.CreateBuilder(args);// This top level property is of type WebApplicationAuthenticationBuilder which derives from AuthenticationBuilder so all// existing authentication configuration methods are available here. It also ensures that the services for authorization are// added if any authentication scheme is added. This property also registers an IConfigureOptions<AuthenticationOptions> along// with a new mechanism to allow individual authentication schemes to have their options set from configuration too// (similar to the way logging does today).builder.Authentication.AddJwtBearer();varapp=builder.Build();// The authentication and authorization middleware are automatically added after the routing middleware by the host if any// authentication scheme is configured via builder.Authenticationapp.MapGet("/hello",()=>"Hello!");// Add authorization requirements to the API definitionapp.MapGet("/hello-protected",()=>"Hello, you are authorized to see this!").RequireAuthorization(p =>p.RequireClaim("scope","myapi:protected-access"));app.Run();
This time the following was different:
No new namespaces were required
No services were explicitly added
Authentication was configured via a top-level property on the builder that is easy to discover
No options needed to be configured in code via callbacks as they're automatically read from app configuration, e.g. appsettings.json (which will be populated by the tool used to create a test JWT)
No middleware was explicitly added
The authorization requirements were defined directly on the endpoint definition as metadata
Today, configuring authentication/authorization for an ASP.NET Core application requires adding services and middleware at different stages of the app startup process. We've seen feedback that users find configuring authnz one of the hardest things about building APIs with ASP.NET Core.
Given authnz is regularly a cross-cutting, top-level concern of configuring an application, and very often the first thing someone wants to do after getting an API working, we should consider making it simpler to discover and configure.
Adding authentication to an app
Here's a minimally functional app at the point where it is ready to have authentication configured:
Adding auth today
To protect the second API today, services must be added, along with two middleware, and finally an authorization requirement defined on the API endpoint itself:
Every one of these changes must be applied in the correct phase of application startup (i.e. called on the right type and put on the right line) in order for the second API to be successfully protected so that only authenticated users can call it. This involved introducing the following concepts:
If access to the protected endpoint is to require more than simply the fact the client is authenticated, then a "policy" must be defined as part of the authorization services being registered in the DI container, and then referred to when adding the endpoint metadata:
While very flexible, this process can seem overly complex for something that many folks consider a simple scenario.
Adding auth via new simplified process
The general idea is to explore promoting authentication and authorization to be more of a first-class concept of
WebApplicationBuilder, as is already the case for logging and configuration, building atop of the existing authentication and authorization primitives in ASP.NET Core.Some proposals to explore:
WebApplicationBuilderto enable configuration of authentication and authorizationWebApplicationBuilderGiven our original example app that's ready for configuring authnz in, consider the following:
This time the following was different:
builderthat is easy to discoverappsettings.json(which will be populated by the tool used to create a test JWT)