2

IdentityServer 2 をカスタマイズして、ID フェデレーション機能を Azure AD (Office 365 など) に提供しました。これには、パッシブ リクエスター フロー用の WS-Federation エンドポイントと、アクティブ クライアント用の WS-Trust があります。WS-Trust の MEX エンドポイントは、POST (Lync が使用する場合) と GET (Windows 10 サインインが使用する場合) の両方に応答して、WS-Trust SOAP の WSDL を返す必要があります。残念ながら、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,references

どんな助けでも大歓迎です!

4

3 に答える 3

2

同じ場所で立ち往生している他の人のために、HTTP GET に応答するように TokenServiceHostFactory を明示的に設定しました。

// 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;
    }
}
于 2017-03-29T11:49:42.990 に答える