怎样配置CRM的SPN

关于SPN

 

服务主体名称,也称为一个SPN,是一种名称,唯一标识一个服务实例。用来验证Kerberos身份验证的SPN的必须正确设置。SPN是Active Directory属性. 但不暴露在AD的管理单元.

 

确保正确的SPN的设置变得非常重要,比如讲CRM, SQL SRS的应用. 如果应用程序分别在不同的服务器上,我们会需要用户凭证从一台服务器传递到另一个台服务器。这个过程称为Kerberos委派。例如,当用户运行了在CRM中的SRS的报表时,我们必须验证CRM,然后将请求发送到SRS服务器。CRM服务器会模拟用户对SRS的请求。如果SPN身份验证不正确,CRM服务器上的授权就会失败,SRS的请求会用NT AUTHORITY \ ANONYMOUS登录, 随后就会导致401身份验证错误。

 

 

SPN 格式

 

SPN的格式是<service class>/<host>:<port>/<service name>.

 

端口号和服务名字是SPN参数的可选项。最常见的就是看到SQL SPN使用端口号及服务名字。

通常你需要定义SQL的port和数据库实列的服务名字。在其他一些场景,SPN也需要定义一些IIS的应用程序。

当Web应用程序/服务没有用标准的HTTP 80端口(HTTP)或443(HTTPS)的监听时, 你需要定义IIS端口. 如果使用默认端口,您不需要使用的IIS服务的SPN. 如果你使用自己定义的端口的话,你就需要定义IIS 的 SPN.

 

 

缺省SPN

 

默认情况下的主机服务类型的SPN会设置在所有计算机帐户下.这个SPN用来表示同时表示NETBIOS 和FQDN.

主机SPN的格式是: HOST/<COMPUTERNAME> 和HOST/<COMPUTERNAME>.<FQDN>.

 

当SQL SERVER 安装时会需要运行SQL service的帐户. SPN会自动注册到这个账户下用MSSQLSvc\<ComputerName>:<Port> 这样的格式.

如果在安装完后你更改SQL的service account,你可能会碰到duplicate SPN 的问题,除非你移掉原用的账户 MSSQLSvc SPN,而使用这个你更改的帐户。

 

 

其他SPN

可能会有其他一些场景需要额外的SPN。如果IIS 应用程序池在一个service account 下运行,你就需要一个SPN。比如你用一个域用户来跑应用程序池而不用默认的network service, 你就会需要设置一个用HTTP service 类型的SPN给这个域用户。如果你的HTTP是加密的话,启用了SSL, 你也需要为这个账户设置HTTP service 类型的SPN。

HTTP/<computer name> and HTTP/<computer name>.<fqdn>.

 

其他的一些场景,比如讲当你创建一个alias/host header的网站,你也需要设置额外的SPN。除了你用host header 来替代计算机名字外,你还需要创建一个HTTP service 类型的SPN去运行在这个网站的Application pool 账户下。

 

HTTP/<hostheader> and HTTP/<hostheader>.<fqdn>.

 

如果在安装完后,运行SQL SERVICE的帐户被更改了,那么这个MSSQLSvr SPN也需要重新设到这个新更改的账户上。

非常常见的是用local system 来安装SQL。这个会使用MSSQLSvc/<COMPUTERNAME>:<PORT> 来注册SPN。如果你需要用其他的域帐户来运行SQL Service, 那你需要移掉原来的这个local system,再注册一个SPN用新更改的域帐户。

 

SPN 的设置

我们可以从任何域服务器上设置SPN如果他们安装了windows support tool 的话。最常用的方法就是用ADSI EDIT 和 SetSPN command line的形式。

 

注意: SPN 必须是唯一的,无论你增加或者删除的时候。

 

ADSI编辑是一个LDAP的编辑器,用来管理对象和属性在AD里。ADSI编辑器允许你浏览组对象,就像Active Directory Users and Computers. 如果你要在ADSI中更改SPN,那你就要先找到计算机或者是用户,然后打开它的属性。找到列表中的SPN然后编辑它。非常容易的增加及删除。

 

如果你是用windows server 2003, 那你需要下载 Support Tools. 如果你是用windows 2008, 你这个工具默认的会被安装。

 

SetSPN是一个命令行工具, 允许您浏览,修改和删除的Active Directory对象的SPN。下面是一些命令行形式的格式:

 

Listing SPN’s: setspn –l <objectname> 用来列出一个对象的SPN设置。

e.g. setspn –l microsoft\CrmAdmin or setspn –l CrmAppServer

Adding SPN’s: setspn – a <service\name> <objectname>. 增加一个SPN给某个对象。

e.g. setspn –a HTTP/crm microsoft\CrmAdmin or setspn –a HTTP/crm CrmAppServer

Removing SPN’s: setspn –d <service\name> <objectname> 移掉一个SPN

e.g. setspn –d HTTP/crm microsoft\CrmAdmin or setspn –d HTTP/crm CrmAppServer

 

在加SPN 之前,最重要的是在AD 的域或者林里,确定SPN没有被另外的帐户所占用。你可以用下面的一些命令来查询SPN。

 

LIDFDE或LDP: 查询所有林中域使用SPN的情况。

还有就是使用querySPN.vbs

 

这篇KB https://support.microsoft.com/kb/321044 描述了怎样使用LIDFDE, LDP, 和querySPN.vbs的。

querySPN.vbs可以搜索整个域树。如果你有多个林,那你需要指定一个林来进行查询。

 

CRM需要使用SPN的场景

 

下面是一些场景需要设置额外的SPN或者是需要把已经存在的SPN 移动到不同的AD对象上.每一个场景列出了具体的配置信息.

 

场景1- host header 添加到站点

Host header “CRM”用端口 80, 这个host header “CRM” 会被加到CRM 网站上. CRM 网站在服务器 CRMAppServer.contoso.com上, 这个网站的应用程序池是用网络服务. 网络服务用的是计算机名,网络服务帐户, 所以我们需要在这里建立一个SPN.

 

下面的SPN需要被加到这个CRMAppServer.contoso.com 对象上.

· HTTP/CRM

· HTTP/CRM.contoso.com

 

首先我们先看是否这个SPN没有被使用. 如果没有SPN的话,会显示 "No SPNs found!", 表明我们可以添加SPN. 下面是用setSPN在命令行模式下设置host header ”CRM”的SPN.

 

· setspn –a HTTP/CRM CrmAppServer

· setspn –a HTTP/CRM.contoso.com CrmAppServer

 

当用Kerberos授权时, 我们需要注意几个地方:我们建议你不要用DNS中的CNAME记录, 而是用A-Record 或者是host record. 如果你用CNAME, 你的应用程序池会不使用 network service. 你可能需要安装下面的hot fix 在IE6 或者IE7 上使用Kerberos 验证:

 

Hotfix1: 当您尝试访问需要基于 Windows XP 的计算机上的 Kerberos 身份验证的网站的 Internet Explorer 中的错误消息:"HTTP 错误 401-未经授权: 由于凭据无效,访问被拒绝"

https://support.microsoft.com/kb/911149/zh-cn

 

hotfix2: 当您尝试使用IE7 访问一个网站用Kerberos 身份验证时会产生错误消息:"HTTP 错误 401-未经授权: 由于凭据无效,访问被拒绝"

https://support.microsoft.com/kb/938305/en-us

场景2 -更改CRM应用程序池用域用户运行

 

CRM网站在CRMAppServer.contoso.com 服务器上. 场景一中,我们用的是host header, 所以当前的应用程序池用的是network service, 就是本地的计算机. 如果当前, 公司想更改应用程序池运用一个域用户CRMService. 这样我们就需要重新设置SPN到这个新的账户下, 并且用HTTP 服务的类型. 原来的SPN设置必须删掉为了避免SPN的重复.

 

1. 你可以通过ADSI或者setSPN工具来增加删除SPN. 下面是我们期望的SPN需要被加在这个对象下. 其他的SPN可能会已经存在在这个对象上,这个取决于安装的服务.

· HOST/CRMAppServer

· HOST/CRMAppServer.contoso.com

· HTTP/CRM

· HTTP/CRM.contoso.com

有两种不同的服务类的SPN注册, 缺省host 的SPN和HTTP 类型的SPN. 当前的HTTP的SPN的需要被删除, 然后增加新的SPN. HOST类型的SPN不需要被删除,因为它属于host 类型,不导致duplicate

· HTTP/CRM

· HTTP/CRM.contoso.com

我们可以用下面的命令来删除:

· setspn –d HTTP/CRM CrmAppServer

· setspn –d HTTP/CRM.contoso.com CrmAppServer

 

2. 我们需要为contoso\CRMService对象添加下面的SPN.这些SPN是server name和 host header. 额外的SPN可能会需要建立如果你用了其他的host header的话。

· HTTP/CRMAppServer

· HTTP/CRMAppServer.contoso.com

· HTTP/CRM

· HTTP/CRM.contoso.com

 

 首先我们需要查看是否有重复的SPN存在,然后我们为这个账户添加上面的SPN. 我们可以用下面的命令来添加新的SPN:

· Setspn –a HTTP/CRMAppServer contoso\CRMService

· Setspn –a HTTP/CRMAppServer.contoso.com contoso\CRMService

· setspn –a HTTP/CRM contoso\CRMService

· setspn –a HTTP/CRM.contoso.com contoso\CRMService

 

场景3- CRM应用程序池使用一个域用户,而其他应用程序池使用其他的不同的域账户。

 

在服务器 CRMAppServer.contoso.com 上跑CRM网站,用5555端口。Host header CRM还是用80端口。我们可以用下面两个地址访问CRM: https://CRMAppServer:5555https://CRM . 应用程序池现在用network service, 但是用户想用域账户CRMService 去跑它。

 

这个服务器CRMAppServer.contoso.com还运行了一个intranet site,它的应用程序池是在IntranetService这个账户下的。这个intranet 站点是在80端口下执行. 这个网站也有一个host header在这个intranet 80的端口上。这个网站可以用https://CRMAppServerhttps://Intranet 访问.

 

在你更改账户的时候,为了验证这个账户在CRMAppPool上的用法是正确的,你需要先注意一些设置, 你可以更了解具体的前提条件通过KB932476。

 

当你更改运行应用程序池的账户时,服务器名字和hostheaders的SPN需要被重新注册在这个新的账户下,用HTTP 服务的类型。

但是这边有个问题是,我们有两个站点,并且用不同的账户, 一个是CRMService, 另外一个是IntranetService. 但是都是用同一个主机名字CRMAppServer.

 

当我们增加 HTTP/CRMAppServer SPN到CRMService 账户下的时候,SPN 会重复. 但是这时候, 我们又不能删除IntranetService上的SPN,因为它会导致在该网站上的身份验证失败。所以我们在设SPN的时候,会通过端口号去识别,这样就可以具备唯一性。

 

1. 确定该SPN 是注册在当前运行应用程序池的账户下。如果当前账户是网络服务, 就是本地计算机对象CRMAppServer.contoso.com。下面的SPN可使用ADSI编辑或SetSPN来删除。下面是我们预期的SPN设置。

OBJECT: CRMAppServer.contoso.com

· HOST/CRMAppServer

· HOST/CRMAppServer.contoso.com

· HTTP/CRM

· HTTP/CRM.contoso.com

OBJECT: contoso\IntranetService

· HTTP/CRMAppServer

· HTTP/CRMAppServer.contoso.com

· HTTP/Intranet

· HTTP/Intranet.contoso.com

 

2. 有两种不同类型的SPN注册在CRMAppServer.contoso.com下。默认的是HOST的SPN,HTTP是用CRM host header。我们可以关注HTTP的SPN。当前CRM host header的HTTP SPN 需要被删掉, 因为当前的HTTP SPN是运行在网络服务(机器名)下的。

 

我们用下面的命令来删除HTTP/CRM 和 HTTP/CRM.contoso.com:

· setspn –d HTTP/CRM CrmAppServer

· setspn –d HTTP/CRM.contoso.com CrmAppServer

 

然后我们可以把SPN加在新的服务账户上

· HTTP/CRM

· HTTP/CRM.contoso.com

 

3. 下面是SPN需要被加到contoso\CRMService对象上。他们是servername和host header的SPN。我们可以用端口号来避免SPN重复。

· HTTP/CRMAppServer:5555

· HTTP/CRMAppServer.cont:5555

· HTTP/CRM

· HTTP/CRM.contoso.com

 

我们用下面的命令来添加CRMService 帐户到 HTTP/CRM 和 HTTP/CRM.contoso.com 上:

· setspn –a HTTP/CRMAppServer:5555 contoso\CRMService

· setspn –a HTTP/CRMAppServer.contoso.com:5555 contoso\CRMService

· setspn –a HTTP/CRM contoso\CRMService

· setspn –a HTTP/CRM.contoso.com contoso\CRMService

 

当我们用缺省的端口号来设置SPN的时候 (80或443), IE6会需要一个hotfix和一个注册表字段来修复Kerberos验证的协议。IE7也是修改那个注册表信息。

 

Internet Explorer 6 无法使用 Kerberos 身份验证协议连接到使用非标准端口在 Windows XP 和 Windows Server 2003 中的网站

 

https://support.microsoft.com/kb/908209/zh-cn

 

 Vivien Zhou

Comments

  • Anonymous
    February 26, 2010
    前两天遇到个 cannot generate sspi context  好像就是这个spn的问题。现在也没有解决呢,晚上照着检查一下看看。