ASP.Net MVC中的LDAP身份验证

use*_*513 27 c# asp.net-mvc

我希望能够通过使用他们的域UserId和Password来验证用户,但默认的ASP.Net MVC应用程序允许用户注册userId和密码然后登录.我该怎么做?

我不希望用户能够注册; 但是,他应该能够输入他的Windows域userId和密码,并由域服务器进行身份验证.

我见过的解决方案(例如Mike的博客)不要求用户输入他/她的UserId或密码.

如何让我的ASP.Net MVC应用程序显示登录表单并根据Windows域对用户进行身份验证?

如果可能,请用样品解释

Kev*_*che 20

这是如何在Web Apps表单身份验证中执行此操作,因此可能需要对MVC进行一些调整.使用asp.net成员资格和角色引擎.设置提供程序以使用Active Directory成员资格提供程序,并使用表单进行身份验证.

<authentication mode="Forms">
  <forms name=".ADAuthCookie" 
         timeout="10"                     
         loginUrl="Login.aspx" 
         defaultUrl="Default.aspx">            
  </forms>
Run Code Online (Sandbox Code Playgroud)

或类似的东西....

提供程序设置如下所示:

<membership defaultProvider="DomainLoginMembershipProvider">
  <providers>
    <add name="DomainLoginMembershipProvider"           
             type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0,Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"           
         connectionStringName="ADConnectionString"
         connectionProtection="Secure"
         connectionUsername="domainuser"
         connectionPassword="pwd"
         attributeMapUsername="sAMAccountName" 
         enableSearchMethods="false"/>
  </providers>
</membership>
Run Code Online (Sandbox Code Playgroud)

连接保护,用户名和密码适用于有权代表系统查询AD的帐户.根据网络的安全性,可能必须进行设置,否则您将无法查询AD以对用户进行身份验证.

您的连接字符串将类似于:

<connectionStrings>
  <add name="ADConnectionString"
       connectionString="LDAP://servername:port#/DC=domainname"/>
</connectionStrings>
Run Code Online (Sandbox Code Playgroud)

连接字符串可以采用多种形式,因此您可能需要针对您的环境进行研究.

对于登录页面,您可能必须执行身份验证方法并测试...

    e.Authenticated = Membership.ValidateUser(username, password);
    if (e.Authenticated == false)...
Run Code Online (Sandbox Code Playgroud)

Stephen Shackow的书"Professional ASP.Net 2.0安全性,成员资格和角色管理"对使用AD成员资格有很好的报道(第12章).它不在MVC的上下文中,但配置和设置将是相同的.


use*_*513 15

谢谢你指出了正确的方向,这就是我最终做的事情

        <authentication mode="Forms">
              <forms loginUrl="~/Account/LogOn" timeout="10"/>
        </authentication>                  

 public bool ValidateUser(string userName, string password)
        {
            bool validation;
            try
            {
                LdapConnection ldc = new LdapConnection(new LdapDirectoryIdentifier((string)null, false, false));
                NetworkCredential nc = new NetworkCredential(userName, password, "DOMAIN NAME HERE");
                ldc.Credential = nc;
                ldc.AuthType = AuthType.Negotiate;
                ldc.Bind(nc); // user has authenticated at this point, as the credentials were used to login to the dc.
                validation = true;
            }
            catch (LdapException)
            {
                validation = false;
            }
            return validation;
        }
Run Code Online (Sandbox Code Playgroud)

我不喜欢这样的事实:我使用try块上的catch来确定用户验证是否成功,但我找不到另一种方法.

  • LdapConnection应该在using(){}块中,以确保它被正确处理 (5认同)

tva*_*son 8

我认为你误解了你引用的博客文章.web.config文件中提供的用户标识和密码是ActiveDirectoryMembershipProvider用于连接AD的用户标识和密码,而不是用户提供的标识和密码.基本上他所说的是为AD成员资格提供者换出SQL成员资格提供程序,并使用编写的代码使其与AD一起使用.这正是你需要做的.如果您根本不想使用成员资格提供程序代码,则可以在感兴趣的域的主体上下文中使用PrincipalContext.ValidateCredentials方法来验证传递给Login方法的凭据.

using (PrincipalContext context = new PrincipalContext( ContextType.Domain, "domain" )) {
    if (context.ValidateCredentials( username, password))
    {
        // log them in
    }
    else
    {
       // set up error message and rerender view
    }
}
Run Code Online (Sandbox Code Playgroud)