【问题标题】:ActiveDirectory Current Username in ASP.NETASP.NET 中的 ActiveDirectory 当前用户名
【发布时间】:2012-05-22 00:13:07
【问题描述】:

我正在尝试让 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 安全设置。

【问题讨论】:

    标签: asp.net active-directory forms-authentication windows-authentication


    【解决方案1】:

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

    此外,混合基于表单和基于 Windows/AD 的身份验证是可行的,但不推荐。如果需要,请参阅this

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

    如果您关闭匿名身份验证并打开 Asp.Net 模拟,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();
    }
    

    【讨论】:

    • 您能否再解释一下您的前两点?你是什​​么意思“如果该数据在表格成员提供者/广告中”。他们是用户,我可以通过用户名查询 AD。 “否则你将不得不查询 AD 来获得他们的名字。” - 如果我知道他们的名字,我可以这样做,但我将如何获得他们的名字呢?
    • 我遇到的问题是Thread.CurrentPrincipal.Identity.Name 是空的,是不是获取不到用户名。
    • 尝试关闭匿名身份验证,这会让人们无需身份验证即可访问网站,这就是为什么他们在查找时没有任何身份。
    【解决方案2】:

    我使用 Windows 身份验证编写的 .Net 应用程序我仍然可以使用 User.Identity.Name 获取 AD 用户名。当然,这通常包括 DC,并返回用户的 SAM 帐户名称。我并没有尝试同时实现两者,但User.Identity.Name 肯定会分开工作

    【讨论】:

      【解决方案3】:

      如果您在活动目录中使用表单身份验证,请尝试以下操作:

      Context.User.Identity.Name
      

      //代码sn-p

      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;
      

      如果有问题,请检查您的申请 模拟方法,根据How To: Use Windows Authentication in ASP.NET 2.0的MSDN文档

      参考ScottGu的文章Recipe: Enabling Windows Authentication within an Intranet ASP.NET Web application

      【讨论】:

      • 注意:在使用表单身份验证时不适用。我已经将它与 ASP.NET MVC 一起使用,并且 System.Web.HttpContext.Current.User 将是一个 System.Web.Security.FormsIdentity 对象。
      【解决方案4】:

      这是我不久前在我的 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 指向活动目录中的不同用户属性

      【讨论】:

      • 问题是HttpContext.Current.User.Identity是空白的,IsAuthenticated是假的,所以我没有用户名,即使我在AD帐户上。
      • 这很奇怪。您是否将 web.config 中的 标记设置为 LDAP 连接?因为,如果是,并且您可以登录,则 HttpContext.Current.User.Identity 不应为 null
      • 对不起,如果它不可读,是为了快速回复,没想到我都复制粘贴了:?检查你的 webconfig 是否至少被映射
      • 我添加了一个 web.config sn-p。
      【解决方案5】:

      我想试试:

      var i = Environment.CurrentUser;

      你也可以使用我的课程: http://pastebin.com/xnYfVsLX

      【讨论】:

      • 我认为这不适用于网络应用程序,我假设这是因为他提到了表单身份验证
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多