1
votes

I'm working on a ASP.Net MVC 5 app and using ASP.Net identity 2, and need to authorize users based on roles and permissions. roles and permissions is not related to each other. for example, to access "action1" action method,( "admin" role ) or ( combination of "role1" and "permission1" ) must exist for him, but other users that is not in "admin" role or combination of ( "role1" and "permission1") is not true for theirs, don't allow to access that action method.

how i can do this scenario?

do claims based authorization useful in this manner? or i must implement Permission entity and custom AuthorizeAttribute? if true how?

best regards

3

3 Answers

2
votes

Check out the ResourceAuthorize attribute in the Thinktecture.IdentityModel.Owin.ResourceAuthorization.Mvc package.

This attribute authorizes a user based on an action (e.g. read) and a resource (e.g. contact details). You can then base whether or not they are allowed to perform that action on a resource based on a claim (e.g. their presence in a role).

See here for a good example.

Might not be exactly what you are looking for, but you can take inspiration and implement your own authorization attribute using similar logic.

1
votes

This is custom made Authorize which checks permission from database. For example you have 3 bools for permission Account,Clients,Configuration and you want to restrict user based on them.

you can add even two permission on one action, for example you have a method which can be accessed by Account and Client permission than you can add following line

Modify this to use roles with permissions in this, this is the easiest and best way to handle it.

[PermissionBasedAuthorize("Client, Account")]   

This method below is which check the bools from database.

public class PermissionBasedAuthorize : AuthorizeAttribute
{
    private List<string> screen { get; set; }

    public PermissionBasedAuthorize(string ScreenNames)
    {
        if (!string.IsNullOrEmpty(ScreenNames))
            screen = ScreenNames.Split(',').ToList();
    }

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        base.OnAuthorization(actionContext);
        var UserId = HttpContext.Current.User.Identity.GetUserId();
        ApplicationContext db = new ApplicationContext();

        var Permissions = db.Permissions.Find(UserId);

        if (screen == null || screen.Count() == 0)
        {
            actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
        }

        bool IsAllowed = false;

        foreach (var item in screen)
            foreach (var property in Permissions.GetType().GetProperties())
            {
                if (property.Name.ToLower().Equals(item.ToLower()))
                {
                    bool Value = (bool)property.GetValue(Permissions, null);
                    if (Value)
                    {
                        IsAllowed = true;
                    }
                    break;
                }
            }

        if (!IsAllowed)
        {
            actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
        }
    }
}
1
votes

I implemented a Permission-based extension for Microsoft Identity 2 membership system. But in this extension, permissions and roles are related together. there is a many-to-many relation between them. Also you can have a complex authentication with combination of roles and permissions. I suppose it can help you to do permission based authentication.

You can do permission authentication in two ways:

First approach:

// GET: /Manage/Index
[AuthorizePermission(Name = "Show_Management", Description = "Show the Management Page.")]
public async Task<ActionResult> Index(ManageMessageId? message)
{
    //...
}

Second approach:

// GET: /Manage/Users
public async Task<ActionResult> Users()
{
    if (await HttpContext.AuthorizePermission(name: "AllUsers_Management", description: "Edit all of the users information."))
    {
        return View(db.GetAllUsers());
    }
    else if (await HttpContext.AuthorizePermission(name: "UnConfirmedUsers_Management", description: "Edit unconfirmed users information."))
    {
        return View(db.GetUnConfirmedUsers());
    }
    else
    {
        return View(new List<User>());
    }
}

Also it's an open source and free extension and you can access to the repository here.