我有一项服务设置为从 ADFS 检索安全令牌并使用该令牌与其他服务进行通信。当我从本地开发机器联系我的 ADFS windowsmixed 端点时,我能够成功地检索到令牌。但是,当我在运行 ADFS 的同一台机器上安装我的服务时,我收到以下错误:
Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint.
我可以使用以下仅获取令牌的代码来重现该错误。当我在我的开发机器上访问远程服务器时,此代码再次有效,但直接在服务器上时它会失败。我在两者上都使用相同的用户凭据。我使用应用程序池凭据和使用以下代码的简单测试客户端在 IIS Web 服务中遇到相同的错误。
private static SecurityToken GetToken()
{
string stsEndpoint = "https://adfsserver.com/adfs/services/trust/13/windowsmixed";
string appliesTo = "http://domain.com/application/myapplication";
var factory = new WSTrustChannelFactory(
new WindowsWSTrustBinding(SecurityMode.TransportWithMessageCredential),
stsEndpoint);
factory.TrustVersion = TrustVersion.WSTrust13;
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointAddress(appliesTo),
KeyType = KeyTypes.Symmetric
};
var channel = factory.CreateChannel();
return channel.Issue(rst);
}
我在 Windows 事件日志中为 ADFS 2.0 调试打开了跟踪。当直接在服务器上点击那个 windowsmixed 端点时,我没有收到任何条目,这让我相信它实际上并没有到达端点。
我确实在安全日志中收到了很多与我正在运行的服务相关的审核失败:请求了对象的句柄。
Subject:
Security ID: DOMAIN\ODI$ODIController
Account Name: ODI$ODIController
Account Domain: DOMAIN
Logon ID: 0x1a574b5
Object:
Object Server: SC Manager
Object Type: SERVICE OBJECT
Object Name: WinHttpAutoProxySvc
Handle ID: 0x0
Process Information:
Process ID: 0x1f8
Process Name: C:\Windows\System32\services.exe
Access Request Information:
Transaction ID: {00000000-0000-0000-0000-000000000000}
Accesses: Query status of service
Start the service
Query information from service
Access Reasons: -
Access Mask: 0x94
Privileges Used for Access Check: -
我能够使用存储的凭据访问 usernamemixed 端点并接收正确的令牌,因此它似乎与验证用户甚至能够与 ADFS 端点通信有关。
如果我在上面的代码中设置了特定的凭据,它就可以连接。这再次让我相信在同一台机器上它没有为我的 Windows 用户传递正确的凭据。
factory.Credentials.Windows.ClientCredential = new System.Net.NetworkCredential("UserID", "password1", "dev.domain");
感谢您提供的任何帮助。
布赖恩