尝试UserPrincipal.FindByIdentity时登录失败错误

本文关键字:失败 错误 登录 UserPrincipal FindByIdentity 尝试 | 更新日期: 2023-09-27 18:08:09

我已经在这个问题上寻找解决方案一段时间了,但不幸的是每个线程都是死胡同。

我正在开发一个c#/ASP.net web应用程序,它只会在我们公司内部使用。在IIS和我的网页中都关闭了匿名访问。配置文件强制IIS使用windows认证用户(Active Dir用户)。

我的问题是,以下代码可以完美地获得所需的(或任何)AD用户:

using System.DirectoryServices.AccountManagement;
... other code ...
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "mydomain", "someADuser", "someADuserpassword");
UserPrincipal winuser = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "samaccountname");
上面PrincipalContext中使用的

"someADuser"是当前通过windows登录的用户,因此经过身份验证,是一个有效的AD用户。使用以下代码(与完全相同的用户仍然登录)给了我一个"登录失败:未知的用户名或错误的密码"错误:

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "mydomain");
UserPrincipal winuser = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "samaccountname");

似乎是UserPrincipal。如果没有在PrincipalContext对象中指定FindByIdentity,则由于某种原因,FindByIdentity不会使用登录用户的经过验证的凭据——这是我不想做的。

是否有可能,ctx不拿起登录的Windows用户出于某种原因,即使必要的设置(我希望)被添加到web。配置:

<authentication mode="Windows"/>
<authorization>
  <deny users="?"/>
</authorization>

和匿名访问是完全禁用IIS?

尝试UserPrincipal.FindByIdentity时登录失败错误

似乎是UserPrincipal。如果没有在PrincipalContext对象中指定FindByIdentity,则由于某种原因,FindByIdentity不会使用登录用户的经过验证的凭据——这是我不想做的。

UserPrincipal。FindByIdentity根本不关心用户的凭据。您只是在执行查询以查看该帐户是否存在。你得到一个错误的原因是因为默认的用户凭证(即身份,你的web应用程序正在运行)没有访问目录,所以它不能执行查找。当您将客户端的凭据传递给PrincipalContext时,问题就会消失,因为您的客户端具有访问目录的有效AD帐户。

您应该调查使用哪个身份来运行应用程序池,并确保它具有对目录的访问权限。

非常烦人,因为我认为如果匿名访问被关闭,当前主体将默认为登录到windows的用户。事实证明,它不是@RogerN所指示的。

使用@TheKingDave提到的以下语句,它基本上模拟了登录到windows的用户,并使当前线程运行在它的主体上,而不是"ASP"(在我的情况下)帐户上。

因为我们域上的所有用户都有对Active Directory的查询/读访问权限,所以获得更多关于他们的细节应该不是问题,这正是我首先想要的。

结束代码(正在测试):

System.Web.HttpContext.Current.Request.LogonUserIdentity.Impersonate();
ctx = new PrincipalContext(ContextType.Domain, System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName);
UserPrincipal winuser = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "whicheveraccount");

希望它能在未来帮助到一些人!谢谢!: -)

我做了很多搜索/研究来解决这个问题,但没有任何工作,最后,我所做的就是将@添加到服务器名,容器,用户名&密码如下:

app.CreatePerOwinContext(() => new PrincipalContext(ContextType.Domain, @"abc.net", @"OU=Customers,DC=abc,DC=net", ContextOptions.SimpleBind, @"abcnet'authuser", @"!$%MyPassword"));

它起作用了。哎!

所以我发现了如何通过冒充的身份。我有一个情况,作为一个管理员,我想自动解锁一个用户帐户。我必须将用户名放入变量中,并像这样传递给函数:

string accountname = @"domain'username";
string admin = "adminusername";
string domain = Environment.UserDomainName;
string password = "password";
string dc = "WIN2K8DC1";  // example host name of domain controller, could use IP
// This determines the domain automatically, no need to specify
// Use the constructor that takes the domain controller name or IP, 
// admin user name, and password
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, dc, admin, password); 
UserPrincipal winuser = UserPrincipal.FindByIdentity(ctx, accountname)
if (winuser != null)
{
    WindowsImpersonationContext wic = Impersonation.doImpersonation(admin, domain, password); //class/function that does the logon of the user and returns the WIC
    if (wic != null)
    {
        winuser.UnlockAccount();
    }
} 
可以在MSDN上找到用于返回WIC的模拟类功能:https://msdn.microsoft.com/en-us/library/w070t6ka (v = vs.110) . aspx