基于角色成员身份或数据关系ASP.NET MVC授权(所有权) [英] ASP.NET MVC Authorization based on role membership or data relation (ownership)
问题描述
我想在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屋!