1

请帮我决定如何为我的项目授权。ASP.Net MVC声明授权和认证

该项目是用ASP.Net MVC编写的,它是一个允许用户通过Active Directory登录的Intranet应用程序。

用户可以是Junior Lecturer,高级讲师,HOD或超级用户。这对于角色来说很简单,但情况比这更复杂,因为这些角色基于您正在查看的任何信息。例如,一名初级讲师只能看到他讲课的学生的信息。

据我所知,这是声称来的地方。我应该为学生分配模块或学生。

但是,这个过程如果进一步复杂化,因为在任何一个地方没有AD用户名和他们的学生/模块列表。

我需要能够检查几个数据库,看看是否应该允许用户查看信息。

有时候,有权查看特定信息的用户不会通过任何这些检查。因此,我将不得不用AD用户名,他们的角色和他们的学科/学生创建一个数据库。

所以我的问题是关于授权。我是否可以对索赔拥有这种程度的控制权,以及如何分配和检查索赔?

如果它不可能 - 我该如何做这个授权?

在每个控制器的每个动作开始时都有一个if语句,这感觉是错误的 - 但这就是我所有的同事都可以想到的。

+1

我确实设法解决一个问题,近一点你最近有什么。我仍然在撰写博客文章,但[这](http://blog.dinklabs.com/2015/11/mvc-fine-grained-identity-access-control-1.html)是我的方法。 –

回答

1

如果您创建一个继承自AuthorizeAttribute的类,那么您可以自由地执行任何您认为合适的复杂授权过程。请参阅我的回答here了解如何操作。

下面是一些代码,我使用的查询和缓存AD角色:

private static Dictionary<Tuple<string, string>, bool> groupIdentityCache = new Dictionary<Tuple<string, string>, bool>(); 

..

public static bool UserHasRole(IIdentity identity, string groupShortName)  
{ 
    // (we rename our actual AD roles to shorter ones relevant to the site 
    // e.g. [MyAuthorizeAttribute(Roles = "Support,Admin")]) 
    if (!AdLongGroupNames.ContainsKey(groupShortName.ToUpper())) return false; 
    string fullADGroupName = AdLongGroupNames[groupShortName.ToUpper()];    
    Tuple<string, string> key = new Tuple<string, string>(identity.Name.ToUpper(), groupShortName.ToUpper()); 
    if (!groupIdentityCache.ContainsKey(key)) 
    { 
     using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, "DOMAINNAME"))  
     { 
      using (GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(principalContext, fullADGroupName)) 
      { 
       using (UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, GetLogin(identity))) 
       { 
        groupIdentityCache[key] = userPrincipal.IsMemberOf(groupPrincipal); 
       } 
      } 
     }     
    }    
    return groupIdentityCache[key]; 
} 

public static string GetLogin(IIdentity identity) 
{ 
    string[] parts = identity.Name.Split('\\'); 
    if (parts.Count() < 2) return parts[0]; else return parts[1]; 
} 

如果您缓存角色成员身份,则还必须清除Session_Start上的缓存以使更改生效。

通过添加到groupIdentityCache字典中,您可以修改此解决方案以包含来自非AD源的角色(例如类成员的数据库等)。修改groupIdentityCache也可以在测试时提供帮助。

0

有一个'if'语句是错误的,它会花费你长时间的迭代和巨大的内存滥用。

基本上,您几乎可以使用authorize属性来控制每个级别的授权。

但是,您确实需要一个精心打造的实体才能这样做,以便不会因为所有规则而迷失方向。建议您在提交之前对您的授权方案有适当的计划。

您可以尝试使用switch语句,这在实践中会更好。

请注意:

Authorization Article,可以帮助你理解。

+0

我应该在哪里使用switch语句?感谢这篇文章 - 问题是虽然这些活动不是我遇到的问题。事实上,我真正需要的唯一活动就是阅读。问题是,该用户是否可以访问此模块?我应该在哪里放置检查代码? – abiNerd