WS-Trust MEX endpoint in IdentityServer 2 returns HTTP 400 for GET requests

1.4k Views Asked by At

We've customised IdentityServer 2 to provide identity federation capability into Azure AD (for Office 365, etc). This has a WS-Federation endpoint for the passive requester flow and WS-Trust for active clients. The MEX endpoint for WS-Trust should return the WSDL for the WS-Trust SOAP in response to both a POST (as Lync uses) and GET (as Windows 10 sign in uses). Unfortunately, it is returning HTTP 400: ws-trust system.servicemodel.protocolexception "There is a problem with the XML that was received from the network".

As can be seen in the source: 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;

An instance of System.ServiceModel.Security.WSTrustServiceHost is being stood up to handle calls to WS-Trust, and handle its metadata. Checking the ServiceMetadataBehavior that is added by default in WSTrustServiceHost ctor, we can see that it does enable metadata for GET over both HTTP and HTTPS. http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Security/WSTrustServiceHost.cs,8c80389f2532b060,references

So I'm a little confused why https://myhost.com/issue/wstrust/mex returns the metadata when hit with a POST, but returns 400 when you send it a GET. The exception is being thrown in a EnqueueMessageAsyncResult.CompleteParseAndEnqueue() in System.ServiceModel http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Channels/HttpPipeline.cs,b347567a68ab778c,references

Any help greatly appreciated!

2

There are 2 best solutions below

4
On BEST ANSWER

For others stuck in the same place, I have explicitly set the TokenServiceHostFactory to respond to 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;
    }
}
0
On

Those who get stuck with this issue, there is a workaround of taking ADFS metadata file and then changing WS-TRUST1.3 endpoints of usernamemixed and certificatemixed with your own WS-Trust13 implementation. Microsoft seems to support only its own ADFS metadata file. I contacted Microsoft support too but they are yet to provide an answer. Although they acknowledge that metadata parsing may be hardcoded to ADFS and not aligned with standard WS-TRUST13 metadata implementation.

        <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>