基于角色成员身份或数据关系ASP.NET MVC授权(所有权) [英] ASP.NET MVC Authorization based on role membership or data relation (ownership)

查看:151
本文介绍了基于角色成员身份或数据关系ASP.NET MVC授权(所有权)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在ASP.NET MVC延长AuthorizeAttribute,使其支持用户的授权的概念,是基于他们的角色成员或相关数据的所有权。我使用LINQ2SQL的数据访问。有一个在<一个类似的问题href=\"http://stackoverflow.com/questions/390930/asp-net-mvc-authorization-using-roles\">http://stackoverflow.com/questions/390930/asp-net-mvc-authorization-using-roles.

I'd like to extend the AuthorizeAttribute in ASP.NET MVC so that it supports the concept of a user's authorization being based on their role membership OR "ownership" of the data in question. I'm using LINQ2SQL for data access. There is a similar question at http://stackoverflow.com/questions/390930/asp-net-mvc-authorization-using-roles.

我在想什么是增加EntityProperty,UserProperty,RouteParameter和JoinTableType参数给我延长AuthorizeAttribute类。前两个是在连接表的属性来检查的名称。所述RouteParameter将路线参数以提取用于EntityProperty的值以匹配的名称。我会使用当前用户名从用户获得的表的用户ID。该JoinTableType参数是表中包含实体和UserProperties该路由参数值和用户ID必须匹配DataContext的类型。

What I'm thinking is adding EntityProperty, UserProperty, RouteParameter, and JoinTableType parameters to my extended AuthorizeAttribute class. The first two would be the names of the properties in the join table to check. The RouteParameter would be the name of the route parameter to extract for the value of the EntityProperty to match. I'd obtain the user id from the user's table using the current user name. The JoinTableType parameter would be the type of the table in the datacontext that contains the Entity and UserProperties that the route parameter value and user id must match.

的基本思路是,在伪code:

The basic idea is, in pseudocode:

 if authorizecore result is true
    user is granted access based on role
 else if user is not authenticated
    redirect to logon
 else if user is related to request
    user is granted access based on relation
 else
    user is not authorized, redirect to not authorized error view

的相关试验将如下所示:

The is related test would look like:

 result = false
 find the matching user from user name
 find the entity property value in route data
 if user exists and entity property value exists
    get table from context matching join table type
    if table exists
       find row in table matching user id and entity property value
       if row exists
          result = true
       endif
    endif
 endif


 return result

我的问题是我怎么在构建LINQ查询使用类型和属性名称?还是我将不得不做这一切与对象和反思。我真的寻找如何使这更容易让其他的建议将是AP $ P $理念pciated为好。我想preFER来,而使用属性比嵌入直接在行动检查,以保持与我怎么处理我的其他动作此一致。

My question is how do I use the type and property names in constructing the LINQ query? Or am I going to have to do all this with object and reflection. I'm really searching for ideas on how to make this easier so other suggestions would be appreciated as well. I'd prefer to use the attribute rather than embed the checking directly in the action to keep this consistent with how I handle my other actions.

推荐答案

我能够使用动态LINQ的扩展从VS2008样本做这在pretty合理的方式。这里的code再$ P $上面psenting第二伪code样品。它通过我最初的单元测试,但我需要使其更加坚固。

I was able to use the Dynamic Linq extensions from the VS2008 samples to do this in a pretty reasonable fashion. Here's the code representing the second pseudocode sample from above. It passes my initial unit test, but I'll need to make it more robust.

用法:

[RoleOrMemberAuthorization( UserTable = "Participants",
                            UserNameProperty = "UserName",
                            UserSelectionProperty = "ParticipantID",
                            JoinTable = "GroupLeaders",
                            EntityProperty = "GroupID",
                            UserEntityProperty = "ParticipantID",
                            RouteParameter = "id",
                            Roles = "SuperUser, ViewGroups" )]

古称:

else if (IsRelated( filterContext,
                    this.GetTable( dc, this.JoinTable ), 
                    this.GetTable( dc, this.UserTable ) ))
{
    SetCachePolicy( filterContext );
}

相关来源:

protected bool IsRelated( AuthorizationContext filterContext,
                          IQueryable joinTable,
                          IQueryable userTable )
{
    bool result = false;
    try
    {
        object entityIdentifier = filterContext.RouteData
                                               .Values[this.RouteParameter];
        object userIdentifier = this.GetUserIdentifer( filterContext, userTable );
        if (userIdentifier != null && entityIdentifier != null)
        {
            result = joinTable.Where( this.EntityProperty + "=@0 and "
                                      + this.UserEntityProperty + "=@1",
                                      entityIdentifier,
                                      userIdentifier )
                              .Count() > 0;
        }
    }
    catch (NullReferenceException) { }
    return result;
}

private object GetUserIdentifer( AuthorizationContext filterContext,
                                 IQueryable userTable )
{
    string userName = filterContext.HttpContext.User.Identity.Name;

    var query = userTable.Where( this.UserNameProperty + "=@0", userName )
                         .Select( this.UserSelectionProperty );

    object userIdentifer = null;
    foreach (var value in query)
    {
        userIdentifer = value;
        break;
    }
    return userIdentifer;
}

private IQueryable GetTable( DataContext context, string name )
{
    PropertyInfo info = context.GetType().GetProperty( name );
    if (info != null)
    {
        return info.GetValue( context, null ) as IQueryable;
    }
    else
    {
        return null;
    }
}

这篇关于基于角色成员身份或数据关系ASP.NET MVC授权(所有权)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆