我们定制了IdentityServer 2,为Azure AD(Office 365等)提供身份联合功能。它有一个用于被动请求者流的WS-Federation端点和用于主动客户端的WS-Trust端点。WS-Trust的MEX端点应返回WS-Trust SOAP的WSDL,以响应POST(Lync使用)和GET(Windows 10登录使用)。不幸的是,它返回了HTTP 400:ws trust system.servicemodel.protocolexception"从网络接收到的XML有问题"。
如来源所示:https://github.com/IdentityServer/IdentityServer2/blob/master/src/Libraries/Thinktecture.IdentityServer.Protocols/WSTrust/TokenServiceHostFactory.cs
var host = new WSTrustServiceHost(config, baseAddresses);
// add behavior for load balancing support
host.Description.Behaviors.Add(new UseRequestHeadersForMetadataAddressBehavior());
// modify address filter mode for load balancing
var serviceBehavior = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
serviceBehavior.AddressFilterMode = AddressFilterMode.Any;
serviceBehavior.IncludeExceptionDetailInFaults = true;
System.ServiceModel.Security.WSTrustServiceHost的一个实例正在被搁置以处理对WS-Trust的调用并处理其元数据。检查WSTrustServiceHost ctor中默认添加的ServiceMetadataBehavior,我们可以看到它确实通过HTTP和HTTPS为GET启用了元数据。http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Security/WSTrustServiceHost.cs,8c80389f2532b060,参考
所以我有点困惑为什么https://myhost.com/issue/wstrust/mex当POST命中时返回元数据,但当发送GET时返回400。在System.ServiceModel中的EnqueueMessageAsyncResult.CompleteParseAndEnqueue()中引发异常http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Channels/HttpPipeline.cs,b347567a68ab778c,参考
非常感谢您的帮助!
对于其他被困在同一个地方的人,我已经明确设置了TokenServiceHostFactory来响应HTTP GET。
// added for AAD Windows 10 sign in - device requests metadata with GET
ServiceMetadataBehavior metad = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (metad == null)
metad = new ServiceMetadataBehavior();
for (int i = 0; i < baseAddresses.Length; i++)
{
// there will be two bindings: one for http and one secure
switch (baseAddresses[i].Scheme)
{
case "http":
metad.HttpGetEnabled = true;
metad.HttpGetUrl = new Uri(baseAddresses[i], "/issue/wstrust/mex");
break;
case "https":
metad.HttpsGetEnabled = true;
metad.HttpsGetUrl = new Uri(baseAddresses[i], "/issue/wstrust/mex");
break;
}
}
那些遇到这个问题的人,有一种解决方法,即获取ADFS元数据文件,然后使用自己的WS-Trust13实现更改usernamemixed和certificatemixed的WS-TRUST1.3端点。微软似乎只支持自己的ADFS元数据文件。我也联系了微软的支持部门,但他们还没有给出答案。尽管他们承认元数据解析可能被硬编码到ADFS,并且与标准WS-TRUST13元数据实现不一致。
<wsdl:port name="CertificateWSTrustBinding_IWSTrust13Async" binding="tns:CertificateWSTrustBinding_IWSTrust13Async">
<soap12:address location="https://sts.gemalto.com/adfs/services/trust/13/certificatemixed"/>
<wsa10:EndpointReference>
<wsa10:Address>https://sts.gemalto.com/adfs/services/trust/13/certificatemixed</wsa10:Address>
</wsa10:EndpointReference>
</wsdl:port>
<wsdl:port name="UserNameWSTrustBinding_IWSTrust13Async" binding="tns:UserNameWSTrustBinding_IWSTrust13Async">
<soap12:address location="https://sts.gemalto.com/adfs/services/trust/13/usernamemixed"/>
<wsa10:EndpointReference>
<wsa10:Address>https://sts.gemalto.com/adfs/services/trust/13/usernamemixed</wsa10:Address>
</wsa10:EndpointReference>
</wsdl:port>