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?
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.
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.
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.
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)
{
}