16

Is it possible that we can access dbcontext to get my table data and session in custom Policy-Based Authorization? Anyone can help how to achieve it?

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

        services.AddSingleton<IAuthorizationHandler, CheckAuthorize>();


public class CheckAuthorize : AuthorizationHandler<CheckAuthorize>, IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CheckAuthorize requirement)
    {

        if () //check session to verify user is logged in or not
        {
            //redirect to login page
        }
        else
        {
            if ()//access dbcontext get data from database table to validate user access
            {
                //redirect to access denied page
            }
        }
        throw new NotImplementedException();

    }
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
WolfPack
  • 215
  • 2
  • 11

1 Answers1

29

Policies can use DI

So, assuming your db context is in DI you could do something like

public class CheckAuthorizeHandler : AuthorizationHandler<CheckAuthorizeRequirement>
{
    MyContext _context;

    public CheckAuthorizeHandler(MyContext context)
    {
        _context = context;
    }

    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context, 
        MyRequirement requirement)
    {
        // Do something with _context
        // Check if the requirement is fulfilled.
        return Task.CompletedTask;
    }
}

Note that when you do this you have to make your requirement a seperate class, you can't do CheckAuthorize : AuthorizationHandler<CheckAuthorize>, IAuthorizationRequirement, so you'd have to do

public CheckAuthorizeRequirement : IAuthorizationRequirement
{
}

And finally you need to register your handler in the DI system

services.AddTransient<IAuthorizationHandler, CheckAuthorizeHandler>();
blowdart
  • 55,577
  • 12
  • 114
  • 149
  • thanks for your respond. i will try on it base on ur code. Then what about get session value and redirect? – WolfPack Sep 20 '16 at 15:32
  • This is all documented. Session is also a DI service, ISession. I have no idea what you mean by redirect. – blowdart Sep 20 '16 at 15:35
  • oh both dbcontext & Session is a DI service. Redirect means if user access validation false, i will bring user to login page, access denied page. – WolfPack Sep 21 '16 at 00:37
  • You don't need to redirect. The cookie middleware will take care of that for you. – blowdart Sep 21 '16 at 01:38
  • With your idea, im now do able to access dbcontext, now working to get session data. Cookie middleware? how can i configure it as i got two condtion, 1 will go to my loginscontroller another will go to my access denied view only. – WolfPack Sep 21 '16 at 01:48
  • It does that already. And it's documented. https://docs.asp.net/en/latest/security/authentication/cookie.html – blowdart Sep 21 '16 at 01:57
  • You will see login if you're not logged in, and forbidden if you are. – blowdart Sep 21 '16 at 01:57
  • You are right. It will go to my login controller. But how can i go to forbidden page? – WolfPack Sep 21 '16 at 02:19
  • You get bounced to the forbidden page if authorisation fails but the user is logged in. This is the difference between 401 and 403 in http. – blowdart Sep 21 '16 at 02:20
  • Means that i set the error code to 403 in order to go to forbidden page? – WolfPack Sep 21 '16 at 02:45
  • No. use the built in authorize attribute and it will be taken care of. I really suggest reading the authorisation docs and not roll your own. – blowdart Sep 21 '16 at 03:01
  • fyi, actually im not using mvc bult-in user identity. i have my own user profile, user group with module access control. – WolfPack Sep 21 '16 at 03:04
  • Authorize will still work if you follow the cookie middleware instructions – blowdart Sep 21 '16 at 03:06
  • i see..but wonder i got 2 type validation, but all straight go to login page. never go to forbidden page. – WolfPack Sep 21 '16 at 03:27
  • Then your system works like no other I know of and you're on your own I'm afraid. – blowdart Sep 21 '16 at 03:27
  • @blowdart For every handler I will had to add this in my `startup.cs`: `services.AddTransient();` `services.AddTransient();` Is it ok like this, so for every policy I create I will add another class? – Offir May 18 '20 at 16:54