8

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

4

5 回答 5

5

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

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

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

如果您关闭匿名身份验证并打开 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();
}
于 2012-05-14T14:05:25.620 回答
1

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

于 2012-05-14T13:49:35.690 回答
1

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

Context.User.Identity.Name

//代码片段

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

参考:
来自 ASP .NET 的 Active Directory 身份验证
如何使用表单身份验证和 Visual Basic .NET 对 Active Directory 进行身份验证 构建安全的 ASP.NET 应用程序:身份验证、授权和安全通信

参考:您可以通过多种方式将 Windows 身份验证与 ASP.NET 一起使用:

  • 无需模拟的 Windows 身份验证。这是默认设置。ASP.NET 使用应用程序的进程标识(默认情况下是 Windows Server 2003 上的网络服务帐户)执行操作和访问资源。

  • 带有模拟的 Windows 身份验证。使用这种方法,您可以模拟经过身份验证的用户并使用该身份来执行操作和访问资源。

  • 具有固定身份模拟的 Windows 身份验证。使用这种方法,您可以模拟一个固定的 Windows 帐户来使用特定身份访问资源。在 Windows Server 2003 上,您应该避免这种模拟方法;相反,使用具有自定义服务标识的自定义应用程序池。

根据文档,您可以获得经过身份验证的用户的 Windows 令牌。

IIdentity WinId= HttpContext.Current.User.Identity;
WindowsIdentity wi = (WindowsIdentity)WinId;

如果有问题,请按照如何:在 ASP.NET 2.0 中使用 Windows 身份验证的 MSDN 文档检查您的应用程序 模拟方法

请参阅 ScottGu 的文章配方:在 Intranet ASP.NET Web 应用程序中启用 Windows 身份验证

于 2012-05-14T14:21:32.670 回答
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.IdentityProperty

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

于 2012-05-14T13:54:40.177 回答
-1

我会尝试:

var i = Environment.CurrentUser;

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

于 2012-05-14T13:48:59.420 回答