ActiveDirectory ASP.NET中的当前用户名

Ech*_*lon 7 asp.net forms-authentication active-directory windows-authentication

我试图让ActiveDirectory和标准表单登录工作,但有一件事阻止了我.我无法获得当前Windows用户的名称.我最接近的是var i = WindowsIdentity.GetCurrent();,但这给了我IIS应用程序池用户的名字.我在IIS中启用了匿名身份验证,表单身份验证和Windows身份验证.我可以从AD加载用户,所以我假设我的web.config设置正确.

编辑:这是我的web.config(使用Facade提供程序):

<membership defaultProvider="HybridMembershipProvider">
      <providers>
        <clear />
        <add name="HybridMembershipProvider" type="MyApp.Data.HybridMembershipProvider" AspNetProviderName="AspNetSqlMembershipProvider" ActiveDirectoryProviderName="ADMembershipProvider" />
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="MyAppConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
        <add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" 
            attributeMapUsername="sAMAccountName" enableSearchMethods="true" attributeMapEmail="mail"/>
      </providers>
    </membership>
Run Code Online (Sandbox Code Playgroud)

编辑2:这是我的IIS安全设置.

IIS安全设置

Ale*_*ore 5

如果您在 IIS 中打开 ASP.Net Impersonation,您可以获得您想要的用户名。这仅在该数据位于表单成员资格提供程序/AD 中时才有效,并且它们不是匿名的。

此外,混合基于表单和基于 Windows/AD 的身份验证是可行的,但不推荐。如果您需要这样做,请查看内容。

编辑:我想我误解了你想要的东西,所以这里是对上述解决方案的高级掩盖:

如果您关闭匿名身份验证并打开 Asp.Net Impersonation,IIS 将在有人访问该站点时执行 401 质询。
如果一切都在同一个域中,Web 浏览器会将您的凭据发送到 IIS,IIS 将根据它的 Active Directory 验证它们,然后 AD 将为 IIS 提供一个身份以供使用。

当您打开 Asp.Net Impersonation 时,IIS 会将该标识绑定到当前线程/请求。因此,在身份验证发生后,您可以从当前线程标识中获取用户名,然后像这样查询 Active Directory:

using System.Threading;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

......

PrincipalContext pc = null;
UserPrincipal principal = null;

try
{
    var username = Thread.CurrentPrincipal.Identity.Name;
    pc = new PrincipalContext(ContextType.Domain, "active.directory.domain.com");
    principal = UserPrincipal.FindByIdentity(pc, username);

    var firstName = principal.GivenName ?? string.Empty
    var lastName = principal.Surname ?? string.Empty
    return string.Format("Hello {0} {1}!", firstName, lastName);
}
catch ...
finally
{
    if (principal != null) principal.Dispose();
    if (pc != null) pc.Dispose();
}
Run Code Online (Sandbox Code Playgroud)