Reputation: 141492
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?
Upvotes: 8
Views: 19864
Reputation: 4267
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.
Upvotes: 1
Reputation: 4012
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.
Upvotes: 2
Reputation: 141
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.
Upvotes: 3
Reputation: 17540
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.
Upvotes: 14
Reputation: 482
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)
{
}
Upvotes: 0