我在IIS的同一服务器上托管了一个WebSite和API。在API(.NET)中,我需要获取使用该网站的用户所属的AD组的列表。它在本地工作(邮递员在IIS Express上调用API),但在我们的服务器上运行时则无效。获取广告组的代码是这样的:
string[] output = null;
string username = GetUserName();
using (var ctx = new PrincipalContext(ContextType.Domain))
using (var user = UserPrincipal.FindByIdentity(ctx, username))
{
if (user != null)
{
output = user.GetGroups() //this returns a collection of principal objects
.Select(x => x.SamAccountName) // select the name. you may change this to choose the display name or whatever you want
.ToArray(); // convert to string array
}
}
正确识别了用户名,并且在localhost和服务器上传递了相同的值,所以这不是问题。行:
using (var user = UserPrincipal.FindByIdentity(ctx, username))
返回异常:
类型的异常 发生“ System.DirectoryServices.DirectoryServicesCOMException” System.DirectoryServices.AccountManagement.dll,但未在中处理 用户代码
可能是IIS设置中的某些内容,但是我不知道是什么。我尝试将DefaultAppPool的标识(分配给Web和API的ApplicationPool)设置为NetworkService,但这没有帮助。
答案 0 :(得分:1)
如果尚未启用,则需要启用Windows身份验证。说明在这里:https://support.microsoft.com/en-in/help/323176/how-to-implement-windows-authentication-and-authorization-in-asp-net
但是基本的想法是您在web.config中使用它:
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true" />
<anonymousAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
然后,您可以使用它来获取当前用户的UserPrincipal
对象:
UserPrincipal.FindByIdentity(domain, User.Identity.Name)
但是由于您的网站还需要使用域凭据向AD进行身份验证,因此您可能仍在使用该帐户时遇到问题。
DefaultAppPool使用服务器本地的帐户,AD不能识别该帐户。您可以在PrincipalContext
构造函数中传递AD凭据,如下所示:
using (var ctx = new PrincipalContext(ContextType.Domain, null, "username", "password"))
我认为NetworkService使用AD计算机帐户进行身份验证,但也许您的服务器未加入域?如果不是,那么您还需要在PrincipalContext
中指定域名:
using (var ctx = new PrincipalContext(ContextType.Domain, "domain.com", "username", "password"))
当您在IIS Express中本地运行它时,它可以工作,因为IIS Express在您的凭据下运行,并使用您的凭据向AD进行身份验证。