8

We understand how to implement authentication and authorization in ASP.NET identity with the WebApi. For instance, we can log a user in and then retrieve both his secure token and role.

We now want to add permissions. For instance, user steve may be in the admin role. Now we want to assign read, edit, and delete permissions to the admin role. How do we do that in ASP.NET Identity? Is there existing permissions infrastructure in ASP.NET Identity?

Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467

5 Answers5

14

I extended ASP.NET Identity to allow for permissions as you describe it. I did it to decouple the security model from your application model. The problem with the traditional approach of putting roles in an AuthorizeAttribute is you have to design your security model the same time as you design your application, and if you make any changes you have to recompile and redeploy your application. With the approach I came up with you define resources and operations in a custom AuthorizeAttribute, where operations are analogous to permissions. Now you decorate methods like this:

[SimpleAuthorize(Resource = "UserProfile", Operation = "modify")]
public ActionResult ModifyUserProfile()
{
    ViewBag.Message = "Modify Your Profile";
    return View();
}

Then you can assign a resource/operation to a role in the database, configuring your security model during deployment and can modify it without redeployment. I wrote about this approach using SimpleMembership here. And later ported it to ASP.NET Identity here. The articles have links to the full source code with reference applications.

Kevin Junghans
  • 17,475
  • 4
  • 45
  • 62
  • 2
    Hello Kevin, I am trying to implement permission in my ASP.NET application. The links you have provided lead to an empty page. I wanted to know how you have implemented permissions. Could you please provide the correct? link to the resources you have implied to in the above answer? – Onsongo Moseti Jul 26 '18 at 15:44
  • 1
    @OnsongoMoseti - The article pointed to a CodePlex project which as been shut down. You could have downloaded the whole project from the page in the link. But I have also moved it to GitHub. The links in the articles have been updated to GitHub and you can reach it here https://github.com/kjunghans/SimpleSecurity . – Kevin Junghans Jul 26 '18 at 19:06
  • Here's a web.archive link for ASP.NET Identity article https://web.archive.org/web/20200812010115/http://kevin-junghans.blogspot.com/2013/11/decoupling-aspnet-identify-from-your.html – dizarter Jul 04 '22 at 16:10
3

You should extend the Identity classes and add this functionality to that. roles and permissions have a many-to-many relation together so you should change the IdentityRole class as something like this:

public class IdentityRole<TKey, TRolePermission>
{
    public string Title { get; set; }

    public virtual ICollection<TRolePermission> Permissions { get; set; }
}

As you can see you want a intermediate object and table named RolePermission. And the Permission class can look like something like this:

public class IdentityPermission<TKey, TRolePermission>
{
    public virtual TKey Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }

    public virtual ICollection<TRolePermission> Roles { get; set; }
}

Then you should create custom AuthorizeAttribute to execute authentication check on the controllers and actions. that could be somthing like this:

public class AuthorizePermissionAttribute : AuthorizeAttribute
{
    public string Name { get; set; }
    public string Description { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        return base.AuthorizeCore(httpContext)
               && Task.Run(() => httpContext.AuthorizePermission(Name, Description, IsGlobal)).Result;
    }
}

You can override the AuthorizeCore method to add the permission authentication to the normal Role-based authentication. Although you can do this easily, i implemented it as an open source Permission-based Identity extension here and you can use it direclty or get inspired from that to do it on your own.

Armin Khodaei
  • 141
  • 2
  • 4
  • 12
  • 1
    Why not use Claims Table as your Permissions store that's already there than creating a new table that's basically going to perform similar functions? – Mosia Thabo Jul 29 '21 at 11:52
1

I find this link as a good approach for dotnet core which can be applied to dotnet framework. in this approach, all things we need is related to claims which are implemented inside Identity and there is no need to Extend Identity.

Navid_pdp11
  • 3,487
  • 3
  • 37
  • 65
1

As I have been here, I believe many more people still find trouble with this question.

Identity Framework is basic and complete, you can basically build a complex app often without having to extend it's underlying model. Keep it simple stupid:

Roles are roles, claims are claims but what exactly does the RoleClaim table store? Well it stores claims for a particular role. And those claims can basically be permissions. Keep it that simple. Here's an example:

Have Predefined Permissions in a dictionary like this:

public static class PredefinedClaims
{
    public static dynamic Get = new Dictionary<string,Claim>{
        {"PermissionToWrite", new Claim("PermissionToWrite","Write") },
        {"PermissionToRead", new Claim("PermissionToWrite","Read") },
    };
}

And let's assume you have a role called User with Id=1. You can create permissions by simply associating that role with claims. Like this:

var GrantPermissions= new List<RoleClaim>(){
  new RoleClaim{
    RoleId = 1,
    PredefinedClaims.Get()["PermissionToWrite"].ClaimType, // <= Set the Permission Type
    PredefinedClaims.Get()["PermissionToWrite"].ClaimType // <= Granted Edit rights.
  },
  // Add more roleclaims intances here
}

And then you can persist the GrantPermissions to your database and they'll be added to your identity. All you need to do is follow the normal procedure of registering your claims to your policies within startup.cs.

Mosia Thabo
  • 4,009
  • 1
  • 14
  • 24
0

We can use Role-based Authorization like

[Authorize(Roles = "Administrator")]
public class StoreManagerController : Controller
{
    // Controller code here
}

We can create enum for permission Item like :

public enum PermissionItems
{ 
        [Group("Users")]
        [Description("Can edit Users")]
        EditUser,
        [Group("Users")]
        [Description("Can view Users")]
        ViewUser,
}

Then we can add this enum values in database according to role.

and check in method by attribute

RequirePermissions(PermissionItems.EditUser)
public ActionResult Edit(int id)
{  

}
Prashant Mehta
  • 484
  • 2
  • 11
  • 30
  • I am wondering about how to add discrete permissions to those roles. – Shaun Luttin Feb 04 '14 at 06:30
  • Is it important to make those permissions discrete? Using the role based authorization infrastructure of ASP.NET MVC shifts the responsibility of processing/rejecting the request away from you, thus reducing the amount of code you have to write overall. I would recommend you to not write more code than you need to for maintainability reasons. – Parth Shah Feb 04 '14 at 06:43
  • 1
    It is important to make permissions discrete, because we want to be able to modify the permissions that each role has. – Shaun Luttin Feb 05 '14 at 20:03