ASP.Net MVC声称授权和身份验证

时间:2015-09-02 09:11:16

标签: c# asp.net-mvc-4 active-directory authorization claims-based-identity

请帮我决定如何为我的项目授权。

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

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

据我了解,这就是索赔的来源。我应该将模块或学生分配给用户。

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

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

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

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

如果不可能 - 我将如何进行此授权?

在每个控制器的每个动作开始时都有一个if语句错了 - 但是我的所有同事都可以提出。

2 个答案:

答案 0 :(得分: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也可以在测试时提供帮助。

答案 1 :(得分:0)

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

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

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

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

请注意:

Authorization Article可能有助于您理解。