【问题标题】:ASP .NET MVC Forms authorization with Active Directory groups使用 Active Directory 组的 ASP .NET MVC 表单授权
【发布时间】:2011-05-19 12:59:50
【问题描述】:

我正在尝试使用 ASP.NET MVC 中的用户和组对 Active Directory 进行身份验证。

我在我的所有类(除了帐户类)上都添加了以下属性:

[Authorize (Roles="SubcontractDB Users")]

此组位于活动目录中的 OU=Area->OU=Groups->OU=Company->CN=SubcontractDB 下。我假设我还需要在 web.config 中设置一个 RoleManager,我尝试如下操作:

<roleManager defaultProvider="ADRoleProvider">
  <providers>
    <clear />
        <add name="ADMembershipProvider" 
             type="System.Web.Security.ActiveDirectoryMembershipProvider" 
             connectionStringName="ADConnectionString" 
             attributeMapUsername="sAMAccountName" />
  </providers>
</roleManager>

我的连接字符串是:

    <add name="ADConnectionString" 
         connectionString="LDAP://blah.com:389/DC=blah,DC=wateva,DC=com"/>

显然我做错了,因为这不起作用。我想要做的就是允许访问属于 AD 中某个组的用户。

【问题讨论】:

  • 有没有办法防止在使用授权时被要求提供凭据?我在 Intranet 站点上使用 Windows 身份验证,需要通过 AD 组进行保护,并且不提示用户输入凭据。

标签: .net asp.net-mvc active-directory


【解决方案1】:

所以我最终实现了自己的授权属性并使用它:

namespace Application.Filters
{  
   public class AuthorizeADAttribute : AuthorizeAttribute
   {
      public string Groups { get; set; }

      protected override bool AuthorizeCore(HttpContextBase httpContext)
      {
         if (base.AuthorizeCore(httpContext))
         {
            /* Return true immediately if the authorization is not 
            locked down to any particular AD group */
            if (String.IsNullOrEmpty(Groups))
               return true;

            // Get the AD groups
            var groups = Groups.Split(',').ToList<string>();

            // Verify that the user is in the given AD group (if any)
            var context = new PrincipalContext(ContextType.Domain, "server");
            var userPrincipal = UserPrincipal.FindByIdentity(context, 
                                                 IdentityType.SamAccountName,
                                                 httpContext.User.Identity.Name);

            foreach (var group in groups)
               if (userPrincipal.IsMemberOf(context, IdentityType.Name, group))
                  return true;
         }
         return false;
      }
   }
}

然后我可以简单地使用上面的控制器或函数

Using Application.Filters;
...
[AuthorizeAD(Groups = "groupname")]

注意:您可以简单地使用 new PrincipalContext(ContextType.Domain);,但是 .NET 4.0 中有一个错误会在 userPrincpal.IsMemberOf(...) 处引发 (0x80005000) 错误。详情请见here。

如果您想知道如何根据授权失败重定向到另一个页面,请在此处查看我的答案:Adding an error message to the view model based on controller attribute in ASP.NET MVC

【讨论】:

  • 我喜欢你在这里所做的,除了你依靠一个简单的 cookie 来缓存某人已被授权的事实。是什么阻止我手动添加 authUserGroups cookie 并绕过初始 AD 检查?
  • 这是错误的做法。请参阅我在 MSDN 上的文章 How to Create an Intranet Site Using ASP.NET MVC msdn.microsoft.com/en-us/library/gg703322(VS.98).aspx 您需要使用 AspNetWindowsTokenRoleProvider 类
  • @RickAnderson-MSFT - 我们专门讨论使用表单身份验证,您的示例使用 Windows 身份验证。虽然我不提倡对 Intranet 站点使用 Forms 身份验证而不是 Windows 身份验证,但这只是让 Forms 身份验证与 AD 一起使用的一种方式,因为在某些情况下,应用程序需要 Forms 身份验证 UI 组件,如登录页面。跨度>
  • IsMember 方法有问题。我通过以下方式解决了它:code var adGroup = userPrincipal.GetAuthorizationGroups(); var groupList = adGroup.ToList(); foreach (var group in groups) if (groupList.FirstOrDefault(g =&gt; g.Name.Contains(group)) != null) return true;
  • @link664 :我在 base.AuthorizeCore(httpContext) 上遇到错误,我相信必须有 AuthorizeCore 类。你能帮我上那门课吗?提前致谢
【解决方案2】:

不再需要在 ASP.NET MVC 3 中为此功能实现您自己的属性。AspNetWindowsTokenRoleProvider 适用于 Active Directory 用户和组。要将此与 AuthorizeAttribute 一起使用,您需要将以下内容添加到您的 web.config:

<authentication mode="Windows" />

<roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider">
   <providers>
      <clear />
      <add 
          name="AspNetWindowsTokenRoleProvider"
          type="System.Web.Security.WindowsTokenRoleProvider" 
          applicationName="/" />
   </providers>
</roleManager>

然后,在您的控制器或操作方法上,您可以像这样引用 Active Directory 组:

[Authorize(Roles = "YOURDOMAIN\\Group1, YOURDOMAIN\\Group2")]

【讨论】:

  • 这在使用 Forms 身份验证时有效还是仅在使用 Windows 身份验证时有效?
  • 我相信我的问题的答案是否定的:stackoverflow.com/questions/2610377/…
  • 这绝对不起作用,不适用于 AD 组,不适用于角色,仅适用于用户(AD 用户),仅 Users = "DOMAIN\\Username" 有效。我不明白为什么 Roles = "DOMAIN\\Group" 对我根本不起作用。
  • 使用上面提到的roleManager 在 MVC5 中对我来说很好:[Authorize(Roles = @"DOMAIN\GROUP")]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-06
  • 1970-01-01
  • 1970-01-01
  • 2017-03-11
相关资源
最近更新 更多