-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Simplify Authentication and Authorization configuration when using WebApplicationBuilder #39855
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks for contacting us. We're moving this issue to the |
Please be very careful when designing this part as this will likely impact authentication handlers that implement Edit: also, in your last example, I don't see where the default authentication scheme is defined. I'd add these 2 questions to your list of things to take into account 😃
|
The intent is that the ordering of the middleware can still be controlled for scenarios where the order matters, similar to what happens today with the implicitly registered routing middleware. But indeed we'll need to consider the interactions you mention. Regarding the default handler, one of my goals with this is to simplify the setup of simpler authentication scenarios, like those where there is only one handler registered. I would very much like it to behave such that if there is only one handler, it becomes the default. For scenarios with multiple handlers, I imagine the default would need to be set by the developer on the |
FYI, here's a concrete case involving the CORS middleware, gRPC-Web and authentication handlers: openiddict/openiddict-core#1385 😃 |
@kevinchalet thanks, that's helpful. @JamesNK FYI. |
Thanks for contacting us. We're moving this issue to the |
Starting to explore this over at https://github.com/DamianEdwards/AspNetCoreDevJwts |
What's the concern with callbacks? We use them everywhere. What's the expected type for How are the default schemes supposed to be set? Especially when there are multiple combine schemes like Identity + Cookies. |
In discussion yesterday we decided there was no concern with the callback and that doing anything different would juts cause more issues.
It's a
Yep we're opening this up for discussion again 😃 The need to set a default scheme when only a single scheme is configured (which is pretty much 100% of the time when folks are starting out adding auth to their API app) is a complication we'd like to avoid. |
To support automatically registering middlewares and services related to authentication when a user registers an authentication handler and for providing a shorthand for invoking extension methods on the namespace Microsoft.AspNetCore.Builder;
class WebApplicationBuilder
{
+ public AuthenticationBuilder Authentication { get; }
} We introduced a new namespace Microsoft.AspNetCore.Authentication;
public class IAuthenticationConfigurationProvider
{
public IConfigurationRoot Configuration { get; }
public IConfiguration GetSection(string name)
} Since we support automatically resolving authentication options from configuration, we introduce a new namespace Microsoft.Extensions.DependencyInjection;
public static class JwtBearerExtensions
{
+ public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder, string authenticationScheme)
} |
Example matching var builder = WebApplication.CreateBuilder(args);
builder.Authentication.AddJwtBearer();
builder.Authorization.AddPolicy("HasProtectedAccess", policy =>
policy.RequireClaim("scope", "myapi:protected-access"));
var app = builder.Build();
app.MapGet("/hello", () => "Hello!");
app.MapGet("/hello-protected", () => "Hello, you are authorized to see this!")
.RequireAuthorization("HasProtectedAccess");
app.MapGet("/hello-also-protected", () => "Hello, you authorized to see this to!")
.RequireAuthorization("HasProtectedAccess");
app.Run(); The builder.Authorization.AddPolicy("HasProtectedAccess", policy => policy.RequireClaim("scope", "myapi:protected-access"));
builder.Authorization.DefaultPolicy = builder.Authorization.GetPolicy("HasProtectedAccess");
// Consider new methods to enable easily setting default/fallback policies by name
builder.Authorization.SetDefaultPolicy("HasProtectedAccess");
builder.Authorization.SetFallbackPolicy("HasProtectedAccess"); The Note this suggestion has a fundamental issue in that the Perhaps instead the {
"Authorization": {
"DefaultPolicy": "HasProtectedAccess",
"FallbackPolicy": "",
"InvokeHandlersAfterFailure": true,
"Policies": {
"HasProtectedAccess": {
"Claims": [
{ "scope" : "myapi:protected-access" }
]
}
}
}
} builder.Authentication.AddJwtBearer();
builder.Authorization.Configure(authz =>
{
// Following is the code-based equivalent of config above
authz.AddPolicy("HasProtectedAccess", policy => policy.RequireClaim("scope", "myapi:protected-access"));
authz.DefaultPolicy = authz.GetPolicy("HasProtectedAccess");
}); Some other potential example policies as defined via configuration: {
"Authorization": {
"DefaultPolicy": "HasProtectedAccess",
"Policies": {
"AuthenticatedUsers": {
"AuthenticationRequired": true
},
"Employees": {
"AuthenticationRequired": true,
"Roles": [ "Employees" ]
},
"OnlyHomers": {
"AuthenticationRequired": true,
"UserName": "Homer"
},
"ApiClients": {
"AuthenticationRequired": true,
// Any unrecognized properties are auto-mapped as claims perhaps?
"scope": [ "myapi:read", "myapi:protected-access" ]
}
}
}
} |
Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:
|
#41520 is the PR with the API change. |
API Review:
namespace Microsoft.AspNetCore.Builder;
class WebApplicationBuilder
{
+ public AuthenticationBuilder Authentication { get; }
}
namespace Microsoft.AspNetCore.Authentication;
+ public class IAuthenticationConfigurationProvider
+ {
+ public IConfiguration GetAuthenticationSchemeConfiguration(string authenticationScheme)
+ }
namespace Microsoft.Extensions.DependencyInjection;
public static class JwtBearerExtensions
{
+ public static AuthenticationBuilder AddJwtBearer(this AuthenticationBuilder builder, string authenticationScheme)
} |
Spun-off the authorization discussion to a new issue #42172 |
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:
WebApplicationBuilder
to enable configuration of authentication and authorizationWebApplicationBuilder
Given our original example app that's ready for configuring authnz in, consider the following:
This time the following was different:
builder
that is easy to discoverappsettings.json
(which will be populated by the tool used to create a test JWT)The text was updated successfully, but these errors were encountered: