Aspnetcore.docs: Howto Use a handler for multiple requirements?

Created on 19 Apr 2018  ·  17Comments  ·  Source: dotnet/AspNetCore.Docs

Issues with Existing Topics

I'm trying to understand Use a handler for multiple requirements. I don't understand how to create my requirement(s). Can this example be expanded?


In the one to one scenario, I do this: public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>. Cool 😎. That must be the glue between the two of them.

What about with public class PermissionHandler : IAuthorizationHandler? Where's the glue?

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("???", policy =>
            policy.Requirements.Add(new ???()));
    });

    services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
}

Most helpful comment

@spottedmahn Thank you for the feedback. In the meantime, here's the sample app associated with the doc: https://github.com/aspnet/Docs/tree/master/aspnetcore/security/authorization/policies/samples/PoliciesAuthApp1.

All 17 comments

@spottedmahn there is no glue at the interface level, your permission handler can handle any requirements you want. Its app specific at this point, what requirements you have, and which handler class is responsible for which requirement.

At the end of the day authorization will succeed as long as all requirements have been met, whether that's one handler succeeding them all, or a bunch of different handlers is up to the app.

You guys are amazing! That's an amazing response time ⚡!

Processing 🤔 your response...

@spottedmahn I've created issue https://github.com/aspnet/Docs/issues/6033 to clarify some things in the doc. Anything else you'd like to see addressed in there?

  • I think it would help to see the ConfigureServices of ReadPermission, EditPermission and DeletePermission
  • I think it would help to see the Policies used in a controller
  • In general, provide a more complete sample.

I'm thinking I can do this... not 100% at this point though.

public class ReadPermission : IAuthorizationRequirement { }
public class EditPermission : IAuthorizationRequirement { }
public class DeletePermission : IAuthorizationRequirement { }
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("Read", policy =>
            policy.Requirements.Add(new ReadPermission()));
        options.AddPolicy("WriteDelete", policy =>
            {
                policy.Requirements.Add(new EditPermission());
                policy.Requirements.Add(new DeletePermission());
            });
    });

    services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
}
[Authorize(Policy = "Read")]
public class DocumentController : Controller
{
    public IActionResult GetDoc() => View();

    [Authorize(Policy = "Delete")]
    public IActionResult DeleteDoc() => View();
}

Hi @HaoK

there is no glue at the interface level

Then why public class MinimumAgeHandler : AuthorizationHandler<MinimumAgeRequirement>? Why not public class MinimumAgeHandler : AuthorizationHandler?

To me, the T implies there is some glue. Pondering... 🤔

@spottedmahn Thank you for the feedback. In the meantime, here's the sample app associated with the doc: https://github.com/aspnet/Docs/tree/master/aspnetcore/security/authorization/policies/samples/PoliciesAuthApp1.

Oh, nice! Perhaps this sample can be update for the Use a handler for multiple requirements example?

Looking at ConfigureServices in that sample I don't see it. Please correct me if I'm wrong.

@spottedmahn Yeah that's from the sugar default implementation, TRequirement isn't on the interface

AuthorizationHandler<TRequirement> is sugar to make it easy to handle one requirement

Thanks @scottaddie. Looks like the same code I see on the docs page. I was hoping for a complete code sample.

image

AuthorizationHandler<TRequirement> is sugar to make it easy to handle one requirement

Ahh, I see, thanks @HaoK!

I really need to follow up on this with a sample, but I’ve implemented this and does feel good to me. 🚫

Before, I had handler logic in individual classes. Not I’ve got 1️⃣ handler class handling many cases.

Seems to go against the single responsibility principal.

It was manageable for our simple case of 3 or 4 IFs, but it doesn’t seem to scale well.

Thoughts 💭?

Isn't that by definition what you are trying to accomplish? (single handler handling multiple requirements), if you want single responsibility, have one handler per requirement

Composability is really what I want to accomplish. I only headed down this path to achieve that.

It is really a separate issue now that I think 🤔 about it. This thread is about how-to handle multiple requirements in one handler, like you stated.

I’ll create a good sample, on a different issue, to describe it, thanks for the quick ⚡️ reply!

Did you get chance to figure out the complete working code from the solution? I am struggling the same issue now. Different examples have different approaches. Really need one to get better understanding.

Was this page helpful?
0 / 5 - 0 ratings