如何使用活动目录组保护Web应用程序?

时间:2012-11-20 03:14:43

标签: c# asp.net-mvc formsauthentication

对不起基本问题,第一次使用C#中的Web MVC ...

我正在为我用C#/ SQL编写的应用程序创建一个Web界面。我已经能够将MVC4框架附加到SQL DB。现在,我希望根据AD中的群组成员资格确保人们可以做些什么。我将我的web.config中的身份验证设置为“Windows”,它正确显示我登录的User.Identity.Name。所以我知道它正在拉动当前登录的用户。此外,我需要能够在Android或ipad设备的情况下验证活动目录域之外的用户。我还没有那么远但是...在大多数情况下,我想尽可能自动验证登录用户,如果不存在则提示输入用户名/密码。

好的,我也知道如何为AD中的用户提取组成员资格。但我需要运行该AD查询并将该信息存储在每个页面上可以访问的位置。然后在每个页面上如何访问该变量?

例如,如果他们无法访问菜单选项,我不想显示菜单选项,因此需要使用变量来显示或不显示受保护的菜单选项。此外,我假设我需要在网页上添加该安全性,以便如果有人试图手动去那里,他们就不能。

我认为出于安全原因,我不想使用会话变量。

过去使用Adobe Flex我使用单例管理会话状态。我在那里进行了搜索,人们说这在C#中可能不是一个好主意。反正这个例子并不多......

你在做什么呢?

1 个答案:

答案 0 :(得分:0)

这是我推荐的。开始寻找ActiveDirectoryMembershipProvider Class的示例。此MembershipProvider与Forms Authentication结合使用,将为您提供一个安全系统来验证用户身份。

通过身份验证后,您需要通过将Active Directory Role Provider(ADRP)(以确定用户组)与Securing your MVC Application的标准方式相结合来授权您的用户访问资源。

为了让您入门,我可以在扩展使用ADRP时创建这些简单的扩展方法(因为我没有使用过ADRP)。

public static class IPrincipalExtensions
{
        private static _adminName = "Administrator";

    public static bool IsAnonymous(this IPrincipal instance)
    {
        return (instance == null);
    }

    public static bool IsAdminOrInRole(this IPrincipal instance, string role)
    {
        if (instance == null
            || instance.Identity == null
            || !instance.Identity.IsAuthenticated)
        {
            return false;
        }

        bool result = instance.IsInRole(role)
                      || instance.IsInRole(IPrincipalExtensions._adminName));

        return result;
    }

}

然后我还扩展了默认AuthorizeAttibute,以便为我提供一个我只能用于管理员的属性:

public class AuthorizeAdministratorAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        bool result = false;
        IPrincipal user = httpContext.User;

        if (user.Identity.IsAuthenticated)
        {
            result = user.IsAdmin();
        }

        return result;
    }
}

这使用我IPrincipalExtensions中提供的相同扩展方法,所以我不再重复。有些人可能会发现这种过度杀伤,因为以下两行相同:

[Authorize("Administrator")]
[AuthorizeAdministrator]

但是,由于第一个示例使用的是字符串,因此简单的错误类型会拒绝访问,如果我决定将角色/组名称更改为“Admins”,则会变得更加困难。因此,如果组更改,使用第二个(我可以说是强类型),我只需要在一个位置更改名称。