Quantcast
Channel: Security
Viewing all articles
Browse latest Browse all 4737

Fine-grained access control for API resources

$
0
0

Hi,

I need a little help. I'm trying to create access control lists that can be used to share resources with others in a similar way to Google Drive/Sites/... For instance, if I have a business object named "My Site", then I should be able to share this site with others, including permissions and (web) visibility rules. The question is, how to implement ACLs using ASP.NET Identity (Claims)? What is the suggested pattern? The following table contains two access control entries for the same resource:

ItemType | ItemId | Scope  | ScopeId | Permission | Visibility
--------------------------------------------------------------
Site     |   1    | Anyone |    -    |  CanView   |   Public
--------------------------------------------------------------
Site     |   1    | User   |    1    |  IsOwner   |   -

ItemType = Site | Document | Playlist | ...
ItemId = The primary key of the shared item.
Scope = Anyone | User
Permission = CanView (10) < CanEdit (20) < IsOwner (30)
Visibility = Private (10) < AnyoneWithLink (20) < Public (30)

And then I can check whether the current user has permission for the requested resource (of course, the method 'HasPermissionAsync()' must check both of the scopes):

public async Task<IHttpActionResult> GetAsync(int id)
{
    int? userId = User.Identity.GetUserId();

    if (await UserManager.HasPermissionAsync(AclPermission.CanView, AclItemType.Site, id, userId) == false)
    {
        return StatusCode(HttpStatusCode.Forbidden);
    }

    ...
}

If I want to get a list of sites shared with the current user, I can join the two tables in one query:

public async Task<IHttpActionResult> GetAllAsync([FromUri] SiteListBindingModel model = null)
{
    int? userId = User.Identity.GetUserId();

    if (userId == null)
    {
        return StatusCode(HttpStatusCode.Forbidden);
    }

    if (model == null)
    {
        model = new SiteListBindingModel();
    }

    IList<SiteResult> list = await SiteManager.FindAllAsync(
       (int)userId,
       model.Name,
       model.OrderBy,
       model.Offset,
       model.Limit,
       model.Fields);

    ...
}

Then I can apply the same permission set to the related items, too.

public async Task<IHttpActionResult> GetAsync(int id)
{
    // Get a page of the site.
    Page page = await SiteManager.GetPageAsync(id);

    if (page == null)
    {
        return NotFound();
    }

    int? userId = User.Identity.GetUserId();

    if (await UserManager.HasPermissionAsync(AclPermission.CanView, AclItemType.Site, page.SiteId, userId) == false)
    {
        return StatusCode(HttpStatusCode.Forbidden);
    }

    ...
}

Facebook also uses some authorization mechanism to manage user pages with roles ( owner, moderator, editor, ... ) but I don't understand how to do it using claims. :)


Viewing all articles
Browse latest Browse all 4737

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>