C# ASP.Net MVC 中的 LDAP 身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1401667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LDAP Authentication in ASP.Net MVC
提问by user99513
I want to be able to authenticate a user by using their domain UserId and Password, but the default ASP.Net MVC application allows the user to register a userId and password and then log in. How can I do this?
我希望能够使用他们的域用户 ID 和密码对用户进行身份验证,但是默认的 ASP.Net MVC 应用程序允许用户注册用户 ID 和密码然后登录。我该怎么做?
I don't want the user to be able to register; however, he should be able to enter his windows domain userId and password and be authenticated by the domain server.
我不希望用户能够注册;但是,他应该能够输入他的 windows 域用户 ID 和密码并通过域服务器进行身份验证。
The solutions I have seen (for example here on Mike's Blog) do not require the user to enter his/her UserId or password.
我看到的解决方案(例如在 Mike 的博客上)不需要用户输入他/她的 UserId 或密码。
How can I get my ASP.Net MVC application to show a log on form and authenticate the user against the windows domain?
如何让我的 ASP.Net MVC 应用程序显示登录表单并针对 Windows 域对用户进行身份验证?
Please explain with a sample if possible
如果可能,请举例说明
采纳答案by Kevin LaBranche
This is how to do it in web Apps forms authentication so it may need some adapting for MVC. Use the asp.net membership and roles engine. Setup the provider to use the Active Directory Membership provider AND ALSO use forms for authentication.
这是如何在 Web Apps 表单身份验证中执行此操作,因此可能需要对 MVC 进行一些调整。使用 asp.net 成员资格和角色引擎。设置提供程序以使用 Active Directory 成员身份提供程序并使用表单进行身份验证。
<authentication mode="Forms">
<forms name=".ADAuthCookie"
timeout="10"
loginUrl="Login.aspx"
defaultUrl="Default.aspx">
</forms>
or something like it....
或类似的东西....
The provider setup will look something like this:
提供程序设置将如下所示:
<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>
The connection protection, user name and pwd are for the account that has access to query AD on behalf of the system. Depending on the security of your network this may have to be setup or you won't be able to query AD to authenticate the user.
连接保护、用户名和密码用于有权代表系统查询 AD 的帐户。根据您网络的安全性,这可能需要设置,否则您将无法查询 AD 来验证用户身份。
Your connection string will look something like:
您的连接字符串将类似于:
<connectionStrings>
<add name="ADConnectionString"
connectionString="LDAP://servername:port#/DC=domainname"/>
</connectionStrings>
The connection string can take many forms so you may have to research it for your environment.
连接字符串可以采用多种形式,因此您可能需要针对您的环境对其进行研究。
For the login page you might have to execute the authentication method and test...
对于登录页面,您可能必须执行身份验证方法并测试...
e.Authenticated = Membership.ValidateUser(username, password);
if (e.Authenticated == false)...
Stephen Shackow's book "Professional ASP.Net 2.0 Security, Membership, and Role Management" has a good coverage on using AD Membership (Chapter 12). It's not in the context of MVC but the configuration and setup would be the same.
Stephen Shackow 的书“Professional ASP.Net 2.0 Security, Membership, and Role Management”很好地介绍了使用 AD Membership(第 12 章)。它不在 MVC 的上下文中,但配置和设置是相同的。
回答by tvanfosson
I think you are misunderstanding the blog post you referenced. The user id and password supplied in the web.config file are the ones used by the ActiveDirectoryMembershipProvider to connect to AD, not the ones supplied by the user. Essentially what he is saying is to swap out the SQL membership provider for an AD membership provider and use the code as written to get it to work with AD. That's exactly what you need to do. If you don't want to use the membership provider code at all, you can use the PrincipalContext.ValidateCredentialsmethod on a principal context for the domain of interest to validate the credentials passed into the Login method.
我认为您误解了您引用的博客文章。web.config 文件中提供的用户 ID 和密码是 ActiveDirectoryMembershipProvider 用于连接 AD 的用户 ID 和密码,而不是用户提供的用户 ID 和密码。本质上,他所说的是将 SQL 成员资格提供程序换成 AD 成员资格提供程序,并使用编写的代码使其与 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
}
}
回答by user99513
thanks for pointing me the right direction, this is what i ended up doing
感谢您为我指出正确的方向,这就是我最终要做的
<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;
}
I don't like the fact that I am using the catch on the try block to determine if the users validation was successful, but I couldn't find another way around it.
我不喜欢我在 try 块上使用 catch 来确定用户验证是否成功的事实,但我找不到其他方法来解决它。
回答by Hanaa
i couldnt find System.Web.Security.ActiveDirectoryMembershipProvider.dll where to find ? also i search in memebership & i found this
我找不到 System.Web.Security.ActiveDirectoryMembershipProvider.dll 在哪里可以找到?我也在会员中搜索并找到了这个
<membership defaultProvider="LdapMembershipProvider">
<providers>
<add name="LdapMembership"
type="Microsoft.Office.Server.Security.LDAPMembershipProvider,
Microsoft.Office.Server,
Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71E9BCE111E9429C"
server="DC"
port="389"
useSSL="false"
userDNAttribute="distinguishedName"
userNameAttribute="sAMAccountName"
userContainer="CN=Users,DC=userName,DC=local"
userObjectClass="person"
userFilter="(|(ObjectCategory=group)(ObjectClass=person))"
scope="Subtree"
otherRequiredUserAttributes="sn,givenname,cn"/>
</providers>
</membership>
回答by Jan ?otola
LdapConnection is a member of System.DirectoryServices.Protocols
namespace (and you have to add System.DirectoryServices.Protocols library to your references)
LdapConnection 是System.DirectoryServices.Protocols
命名空间的成员(并且您必须将 System.DirectoryServices.Protocols 库添加到您的引用中)