question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow direct configuration of authorization policies via endpoint metadata

See original GitHub issue

Relates to #34545

We should allow the definition and/or application of authorization policies to specific endpoints via endpoint metadata at the time they’re declared. This will make configuration of resource authorization for Minimal API style applications much simpler and more inline with the principals of Minimal APIs while still enabling re-use of policies via language features rather than relying on their definition at the time authorization is added to DI.

The AuthorizationMiddleware would be updated to retrieve metadata for the current request and ensure any instances that implement IAuthorizationRequirement are passed to the IAuthorizationService for evaluation (e.g. as IAuthorizationHandler or IAuthorizeData, etc.).

New extension methods would be added to enable setting AuthorizationPolicy on endpoint definitions, as well as methods for setting IAuthorizationRequirement, IAuthorizationHandler or IAuthorizeData as metadata:

// Set authorization metadata via an instance of AuthorizationPolicy
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, AuthorizationPolicy policy) where TBuilder : IEndpointConventionBuilder;

// Set authorization metadata via a callback accepting Action<AuthorizationPolicyBuilder>
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, Action<AuthorizationPolicyBuilder> configurePolicy) where TBuilder : IEndpointConventionBuilder;

// Set authoriziation metadata via an instance of IAuthorizationRequirement
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, IAuthorizationRequirement authoriziationRequirement) where TBuilder : IEndpointConventionBuilder;

// Set authoriziation metadata via an instance of IAuthorizationHandler
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, IAuthorizationHandler authoriziationHandler) where TBuilder : IEndpointConventionBuilder;

// Set authoriziation metadata via an instance of IAuthorizeData
public static TBuilder RequireAuthorization<TBuilder>(this TBuilder builder, IAuthorizeData authorizeData) where TBuilder : IEndpointConventionBuilder;

Example usage:

...
app.UseAuthentication();
app.UseAuthorization();

// Create and use a policy on multiple endpoints
var policy = new AuthorizationPolicyBuilder()
    .RequireAuthenticatedUser()
    .RequireClaim("some:claim", "this-value")
    .Build();

app.MapGet("/protected", () => "you are allowed!")
    .RequireAuthorization(policy);

app.MapGet("/also-protected", () => "you are allowed!")
    .RequireAuthorization(policy);

// Create and pass a policy inline to the endpoint definition
app.MapGet("/fowlers-only-policy", () => "you are allowed!")
    .RequireAuthorization(new AuthorizationPolicyBuilder().RequireUserName("Fowler").Build());

// Define a policy directly on the endpoint via a callback accepting Action<AuthorizationPolicyBuilder>
app.MapGet("/fowlers-only-builder", () => "you are allowed!")
    .RequireAuthorization(p => p.RequireUserName("Fowler"));

// Use a custom attribute that implements IAuthorizationRequirement and IAuthorizationHandler to allow declarative metadata based authorization
app.MapGet("/fowlers-only-attribute", [RequiresUsername("Fowler")] () =>"you are allowed!");

// Use the attribute imperatively
app.MapGet("/fowlers-only-inline", () => "you are allowed!")
    .RequireAuthorization(new RequiresUsernameAttribute("Fowler"));
...

public class RequiresUsernameAttribute : Attribute, IAuthorizationHandler, IAuthorizationRequirement
{
    public RequiresUsernameAttribute(string username)
    {
        Username = username;
    }

    public string Username { get; set; }

    public Task HandleAsync(AuthorizationHandlerContext context)
    {
        if (context.User.Identity?.Name == Username)
        {
            context.Succeed(this);
        }

        return Task.CompletedTask;
    }
}

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:27 (27 by maintainers)

github_iconTop GitHub Comments

2reactions
HaoKcommented, Jul 7, 2022

I’m using this to track the authz caching work discussed to speed up the hot path so endpoints don’t combine authz policies every time

1reaction
davidfowlcommented, Apr 27, 2022

I think we just need to throw for this metadata. @DamianEdwards is looking at auto injecting middlware in the web application builder cases if you configure auth.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Routing in ASP.NET Core
Discover how ASP.NET Core routing is responsible for matching HTTP requests and dispatching to executable endpoints.
Read more >
What's new in ASP.NET Core 8.0
IAuthorizationRequirementData. Prior to ASP.NET Core 8, adding a parameterized authorization policy to an endpoint required implementing an:.
Read more >
Policies | Vault
Policies are how authorization is done in Vault, allowing you to restrict which parts of Vault a user can access.
Read more >
Authorization Services Guide
Specifies how policies are enforced when processing authorization requests sent to the server.
Read more >
Configuring Endpoint Profiling Policies
Cisco ISE allows a global configuration to issue a Change of Authorization (CoA) for endpoints that are already authenticated to enter your network....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found