3

I am trying to see if there is something "out of the box" in ASP.net5 for authorization for my application needs. I am using a group/permission based approach for authorization. Using Identity3 I am using Role as Group and then I have created permissions from this. Each permission has a resource that it links to and 1 or more values, like:

Resource = Page, Permissions = Add, Update, View, Delete

Another complication is that the groups have dynamic names, and dynamic permissions!!

I have started to read about authorization in ASP.net5 and it seems that I have found something called Policies, which sound good. It seems to force you to use Claims, which is possible if I use a ClaimsTransformer to get all my permissions and add them as claims from the Db. But am I right in thinking that I would have to create a policy for each Permission, on each resource? That seems like a lot of setup.

Is there anything that I do not know about is already built in ASP.net5 that I could use? Like an attribute like this

[Authorize("Page", "Delete")]

Which I could add to the PageController Delete method.

If I have to use some sort of service and DI that into the controller to implement this, then that would be fine as well.

Gillardo
  • 9,518
  • 18
  • 73
  • 141
  • In asp.net. they nothing change except the location and folder structure yes some new things like startup,cs file but not any change in core functionality in mvc work flow. so please look once again all over the code and references. if everything is fine it will work. – Piyush Barua Jul 20 '16 at 13:04

4 Answers4

0

There is a ClaimsPrincipalPermissionAttribute that can fit to your requirements.

Or you can implement your own AuthorizeAttribute.

Community
  • 1
  • 1
Thomas
  • 24,234
  • 6
  • 81
  • 125
0

I use AspNet.Security.OpenIdConnect.Server for authorization. But you can also have a look at OpenIddict

In any case you can add the Authorize attribute to any method you want like this

[Authorize(Roles = "Administrator,SimpleUser,AnOtherRole")]
public void MyMethod() {}
Manos Pasgiannis
  • 1,693
  • 1
  • 18
  • 30
0

Resource based authorization might fulfill your needs, but I am a little confused with the page being the resource, rather than what the page acts upon.

Taking your Page/Delete combination, I would imagine that rather than the resource being Page, your Page Delete action takes a parameter, indicating the page that is to be deleted? (If this is not the case then this approach isn't going to work of course)

In this case you'd do something like

[Authorize]
public class PageController : Controller
{
    IAuthorizationService _authorizationService;

    public PageController(IAuthorizationService authorizationService)
    {
        _authorizationService = authorizationService;
    }

    public Delete(int pageId)
    {
        var page = pageRepo.GetPage(pageId);
        if (await authorizationService.AuthorizeAsync(User, page,  Operations.Delete))
        {
            return View(page);
        }
        else
        {
            return new ChallengeResult();
        }
    }
}

In order to enable this you're write a handler based on page and an Operations requirement (or any old requirement, but a parameterized operations requirement means you can write a single handler and branch accordingly).

We tried very hard to move away from putting data in the attribute, and move it into requirements, because data in attributes is, to be frank, a maintenance nightmare.

One other thing to note; as handlers are resolved through DI you could inject your user to permissions resolver into the handler, which would avoid using claims transformation.

blowdart
  • 55,577
  • 12
  • 114
  • 149
  • Maybe "page" was a bad name, but that is the name of my object. So this is in a PageController (could be called Company, contact or whatever). I do not need to validate against a model, but i do need to check if the user has a permission (i suppose i could just swap page for permissions though?). Can this be done using this method, as i prefer this to using an attribute. Also what is ```Operations.Delete```? – Gillardo Jan 29 '16 at 14:46
  • First follow the link at the start of the answer. That goes into what Operations are. – blowdart Jan 29 '16 at 14:48
  • Second - what resource & permissions are you checking against that don't need an instance? Adding a new "Company"? Edit permissions on a Company would require the company itself. If it was add, well you could just either go the resource route and pass in a new Company(), or you have something like a CompanyPermission claim, and put CRUD type permissions in it, then use a claims checking policy on the company controller than checks if a user has any Company access, then drill in further on each controller method – blowdart Jan 29 '16 at 14:51
-2

ASP.NET provides authentication mechanism out of the box which is easy to use, example:

public class HomeController : Controller
{
    [Authorize]
    public ActionResult Index()
    {
        ViewBag.Message = "This can be viewed only by authenticated users only";
        return View();
    }

    [Authorize(Roles="admin")]
    public ActionResult AdminIndex()
    {
        ViewBag.Message = "This can be viewed only by users in Admin role only";
        return View();
    }
}

Check this tutorial

Or if you want more sophisticated mechanism you can implement your own memberhsip provider based on the ASP.NET Membership Provider

Fourat
  • 2,366
  • 4
  • 38
  • 53
  • This is not relevant to asp.net5, also roles (groups) are dynamic – Gillardo Jan 29 '16 at 09:48
  • That is part of the .net framework for web apps, you can use it with any .net version and more importantly I assure you it does what you initially asked in your question. – Fourat Jan 29 '16 at 09:59
  • @Fourat No, that does not. If the roles are dynamic, this does not meet the question's requirements. You've hardcoded `admin` role to have access to the AdminIndex. That's not dynamic. – mason Jan 29 '16 at 14:17
  • @mason Please read the tutorial, the Authorize attribute takes a Roles parameter with is a string, you can hardcode that string, get it from XML, load it in an enumerable, get it from a database ... it's up to you. – Fourat Feb 01 '16 at 15:09
  • You have not shown how to make it dynamic in your answer. Nor do I believe that's possible with the built in attribute. You'll get an error: `An attribute argument must be a constant expression, typeof expression, or array creation expression of an attribute parameter type.` – mason Feb 01 '16 at 15:17