我正在尝试让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安全设置。
答案 0 :(得分:4)
如果您在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();
}
答案 1 :(得分:1)
我编写的.Net应用程序,我已经使用过Windows身份验证,我仍然可以使用User.Identity.Name
来获取AD用户名。这当然通常包括DC,并返回用户SAM帐户名称。我并没有尝试同时实现这两个,但User.Identity.Name
肯定是单独工作
答案 2 :(得分:1)
如果您对活动目录使用表单身份验证,请尝试此操作:
Context.User.Identity.Name
// code snippet
sub Page_Load(sender as object, e as EventArgs)
lblName.Text = "Hello " + Context.User.Identity.Name & "."
lblAuthType.Text = "You were authenticated using " & Context.User.Identity.AuthenticationType & "."
end sub
价:
Active Directory Authentication from ASP .NET
How to authenticate against the Active Directory by using forms authentication and Visual Basic .NET
Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication
价: 您可以通过多种方式对ASP.NET使用Windows身份验证:
没有假冒的Windows身份验证。这是默认设置。 ASP.NET使用应用程序的进程标识执行操作和访问资源,默认情况下,该标识是Windows Server 2003上的网络服务帐户。
带模拟的Windows身份验证。使用此方法,您可以模拟经过身份验证的用户并使用该标识执行操作和访问资源。
具有固定身份模拟的Windows身份验证。使用此方法,您可以模拟固定的Windows帐户以使用特定标识访问资源。在Windows Server 2003上,您应该避免使用此模拟方法;相反,请使用具有自定义服务标识的自定义应用程序池。
根据文档,您可以获取经过身份验证的用户的Windows令牌。
IIdentity WinId= HttpContext.Current.User.Identity;
WindowsIdentity wi = (WindowsIdentity)WinId;
如果出现问题,请检查您的申请 根据{{3}}
的MSDN文档模拟方法
参考ScottGu的文章How To: Use Windows Authentication in ASP.NET 2.0
答案 3 :(得分:0)
这是我在不久前在我的ASP.NET MVC应用程序中使用的一段代码,它对我有帮助,不知道它是否会对你有帮助,你可以自由检查
private static void CheckIfUserExists(string p)
{
try
{
var user = (from x in Data.EntityDB.UserInfoes where x.SAMAccountName == p select x).FirstOrDefault();
DirectoryEntry entry = new DirectoryEntry(Properties.Settings.Default.LDAPPath); //this is the connection to your active directory
DirectorySearcher search = new DirectorySearcher(entry);
search.PropertiesToLoad.Add("*");
search.Filter = "(&(sAMAccountName=" + p + ")(objectCategory=person))";
SearchResult searchResult = search.FindOne();
//If the user under the alias is not found, Add a new user. Else, update his current data
if (user == null)
{
XXXXXXX.Models.UserInfo newUserEntry = new Models.UserInfo
{
SAMAccountName = p,
First_Name = searchResult.Properties.Contains("givenName") ? searchResult.Properties["givenName"][0].ToString() : string.Empty,
Last_Name = searchResult.Properties.Contains("sn") ? searchResult.Properties["sn"][0].ToString() : string.Empty,
Title = searchResult.Properties.Contains("title") ? searchResult.Properties["title"][0].ToString() : string.Empty,
Office = searchResult.Properties.Contains("l") ? searchResult.Properties["l"][0].ToString() : string.Empty,
Country = searchResult.Properties.Contains("c") ? searchResult.Properties["c"][0].ToString() : string.Empty,
Telephone = searchResult.Properties.Contains("telephoneNumber") ? searchResult.Properties["telephoneNumber"][0].ToString() : string.Empty,
Mobile_Phone = searchResult.Properties.Contains("mobile") ? searchResult.Properties["mobile"][0].ToString() : string.Empty,
Email_Address = searchResult.Properties.Contains("mail") ? searchResult.Properties["mail"][0].ToString() : string.Empty,
Image_Path = string.Format(Properties.Settings.Default.UserPicturePath, p),
LastUpdate = DateTime.Now,
};
<强>更新强>
请注意,我还在此提取中查询了另一个数据库,忽略了所有Linq语句。 DirectoryEntry
,DirectorySearcher
和SearchResult
课程可以帮助您满足您的需求。
更新2
变量p可以由HttpContext.Current.User.Identity
属性
更新3 这是LDAP名称的当前列表(您可以在其中看到searchResult.Properties.Contains(“”)Over here,它指向活动目录中的不同用户属性
答案 4 :(得分:-1)