ActiveDirectory ASP.NET中的当前用户名

时间:2012-05-14 13:44:03

标签: asp.net active-directory forms-authentication 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>

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

IIS Security setup

5 个答案:

答案 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语句。 DirectoryEntryDirectorySearcherSearchResult课程可以帮助您满足您的需求。

更新2 变量p可以由HttpContext.Current.User.Identity属性

替换

更新3 这是LDAP名称的当前列表(您可以在其中看到searchResult.Properties.Contains(“”)Over here,它指向活动目录中的不同用户属性

答案 4 :(得分:-1)

我试试看:

var i = Environment.CurrentUser;

你也可以使用我的班级: http://pastebin.com/xnYfVsLX