我试图让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>
编辑2:这是我的IIS安全设置.
解决方法
如果在IIS中打开ASP.Net Impersonation,则可以获得所需的用户名.这仅在数据位于表单成员资格提供程序/ AD中时才有效,并且它们不是匿名的.
此外,混合基于表单和基于Windows / AD的身份验证是可行的,但不推荐.如果需要,请参阅this.
编辑:我认为我误解了你想要的东西,所以这里是对上述解决方案的一个高级别的掩饰:
如果您关闭匿名身份验证,并打开Asp.Net模拟,IIS将在有人访问该站点时执行401挑战.
如果所有内容都在同一个域中,则Web浏览器会将您的凭据发送到IIS,IIS将根据它的Active Directory验证它们,然后AD将为IIS提供一个身份可以使用.
当您打开Asp.Net模拟时,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(); }