IIS 7 上 Web 服务的 ServicePrincipleName 设置

IIS 7 上 Web 服务的 ServicePrincipleName 设置

我很困惑。

考虑以下:

  • 具有名为 DOM 的域的 Active Directory 环境
  • 一个具有 NetBIOS 名称 VS1 的 IIS 7 盒
  • DNS 记录为 VS1 提供别名 pineapple.london.uk.corp
  • 作为 DOM\PineappleService 运行的应用程序池
  • 已启用 Windows 身份验证。
  • 客户端使用 HttpWebRequest 调用盒子上的 XML/JSON ASP.NET 服务。

该服务会调用网络上的工作站来收集信息。这在开发过程中很有效,我使用 IIS Express 来运行它,因为 IISX 只是一个 .exe

在生产中,服务运行良好,身份验证正常,但调用导致服务(作为 PineappleService 运行)访问网络上的内容的函数失败。

我怀疑存在 SPN 注册问题,但我不知道要设置什么 SPN。

最近,我偶然发现了这篇文章,它似乎与其他一些文章的观点相悖:

http://blogs.msdn.com/b/webtopics/archive/2009/01/19/service-principal-name-spn-checklist-for-kerberos-authentication-with-iis-7-0.aspx

请注意

SPN 要求与上述相同。您不必为 Domain1\Username1 添加 http/ 之类的 SPN,这与 IIS 6.0 不同(在 IIS 6.0 中,我们必须为应用程序池标识添加 http/ 形式的 SPN)。

所以我不知道什么才是对的。我不知道是否需要注册 HTTP SPN 或 HOST SPN,或者使用 DNS 别名或 NetBIOS 名称,并将它们设置在 PineappleService 帐户上或 VS1 计算机帐户上。

我无法判断当我尝试某些操作时是否存在 AD 复制速度慢的问题,这意味着我必须在反复试验之间等待一个小时。

现在一切都变得太复杂了。我做系统操作员和开发人员已经 15 年了,我感觉域名、工作站、权利和政策即将终结。一切都变得太过复杂了。

感谢您的帮助。

路加

答案1

除非在开发中对它进行了与生产中完全相同的配置和测试,否则不应尝试此操作。使用 Windows 身份验证和模拟 IIS 和自定义应用程序可能非常复杂。即使它能够在没有准确反映生产的开发环境的情况下奇迹般地在生产中工作,如果您必须调查问题,您也会完全不知所措。

血清型蛋白

创建 SPN 时,通常会为 fqdn 和短名称创建 SPN。示例:

setspn.exe -A http/computer  
setspn.exe -A http/computer.domain.com  

建议这些名称与 Windows 2000 之前的名称(netbios 名称)和连接到服务时将使用的 dns 名称相匹配。如果这些都不是用于连接到服务的名称,则该名称也应该有一个 SPN。

在不同帐户/计算机上为同一服务/名称注册的重复 SPN 是 Kerberos 委派不起作用的常见原因。Setspn 很乐意让您创建重复的 SPN。Microsoft 已发布一个修补程序来纠正此行为:

在 Windows 7 或 Windows Server 2008 R2 中将 setspn 命令与 -a 开关一起运行时,会注册重复的 SPN
https://support.microsoft.com/kb/2717045

服务所在的目标计算机需要 SPN。

   HTTP/computername.company.com
   HTTP/computername

值得信任的授权

需要将执行模拟的计算机或用户帐户指定为受信任的委派帐户。如果用户帐户正在执行模拟,则执行模拟的计算机帐户也必须以相同的方式配置为受信任的委派帐户。

在 Active Directory 用户和计算机中,单击计算机或用户帐户上的“委派”选项卡。(除非用户帐户具有 SPN,否则它不会显示“委派”选项卡。可能需要为用户帐户分配一个 SPN(如 RPC/用户名)才能显示“委派”选项卡)。

在委派选项卡上,选择“信任此用户/计算机委派任何服务(仅 Kerberos)”进行无约束委派。

对于约束委派,选择“仅信任此用户/计算机委派指定服务”。选择“使用任何身份验证协议”。您可以单击“添加”,浏览到公布服务 SPN 的计算机,然后添加它们。请注意,当您运行 setspn.exe -L domain\useraccount 时,这些不会显示为 SPN。

委托模型

您需要确定使用哪种委托模型。此决定可能是出于安全原因。

不受约束允许计算机或服务帐户冒充任何用户。此功能非常强大,但许多组织都避免使用此功能。

约束委派将模拟活动限制在执行模拟的服务帐户可以连接的特定目标计算机和服务(HTTP、CIFS 等)。它还具有额外的便利性,即允许模拟任何帐户,无需拥有该帐户的凭证或预先存在的 Windows/Kerberos 安全令牌

多个域

如果 FE/BE 服务器位于不同的域,则约束委派不起作用。

使用约束委派,执行模拟的帐户/计算机必须与目标资源/服务位于同一域中。此域通常是“资源”域。被模拟的帐户可能位于任何受信任的域中,包括其他林中的受信任域。

提升权限

执行模拟的用户帐户必须在运行执行模拟的代码的计算机上拥有 SetTCB 权限(作为操作系统的一部分)。请注意,在 Windows Vista/7/2008 上,只有具有高完整性级别的进程才可以拥有 SetTCB 权限,因此可能需要将帐户添加到本地管理员组。

授权用户身份必须是执行模拟的计算机上本地用户组的成员。

作为操作系统的一部分,可以使用 gpedit.msc 或 gpmc.msc 进行分配。它位于计算机 > Windows 设置 > 安全设置 > 本地策略 > 用户权限分配下。

Kerberos 版本 5 身份验证协议的工作原理
http://technet.microsoft.com/en-us/library/cc772815%28WS.10%29.aspx

  • 如果选择了“仅使用 Kerberos”选项,则该帐户将使用约束委派而不进行协议转换。
  • 如果选择了“使用任何身份验证协议”选项,则该帐户正在使用约束委派具有协议转换。

呼!正确配置所有配置后,您可以将所有内容提炼为一个易于排除故障的简单测试用例。假设您为 CIFS\fileserver.company.com 创建了一个 SPN,并希望模拟[电子邮件保护]并访问该服务器上的共享:

// no password required with constrained delegation
using (WindowsIdentity id = new WindowsIdentity("[email protected]"))
using (WindowsImpersonationContext wic = id.Impersonate())
{
    // ImpersonationLevel will be "Impersonation" when constrained delegation is setup correctly
    // It will be "Identification" if the account performing impersonation does not have SetTCB privilege
    Debug.WriteLine("ImpersonationLevel: " + id.ImpersonationLevel);
    // Authentication type should be "Kerberos"
    Debug.WriteLine("AuthenticationType: " + id.AuthenticationType);
    Debug.WriteLine("Username: " + WindowsIdentity.GetCurrent().Name);

    Debug.WriteLine("Groups:");
    foreach (IdentityReference identity in id.Groups)
    {
        NTAccount ntaccount = identity.Translate(typeof (NTAccount)) as NTAccount;
        Debug.WriteLine("Account: " + ntaccount.Value + " SID: " + identity.Value);
    }

    // This will fail with access denied if constrained delegation is not setup properly.  
    // On the target server/resource, if it fails it may show an attempt to logon using anonymous
    string[] fileNames = Directory.GetFiles(@"\\fileserver.company.com\ShareName");
    foreach (string fileName in fileNames)
    {
        Console.WriteLine(fileName);
    }
}

答案2

这很可能根本不是 SPN 问题。更可能的是,您的服务帐户 (PineappleService) 下运行的应用程序池没有权限访问网络上的资源。您实际上没有提供任何错误消息,但这听起来确实像是一个简单的权限问题。

您需要确保您的服务帐户可以访问您想要获取的任何内容(您应该在问题中详细说明),无论是文件、信息等。

为了测试,您可以将您的服务帐户设置为域中的管理员,但您肯定不应该将其保留为后期生产部署。

相关内容