diff --git a/src/System.Private.ServiceModel/tests/Common/Scenarios/ScenarioTestHelpers.cs b/src/System.Private.ServiceModel/tests/Common/Scenarios/ScenarioTestHelpers.cs index c9f6eab72a2..4c95129cee6 100644 --- a/src/System.Private.ServiceModel/tests/Common/Scenarios/ScenarioTestHelpers.cs +++ b/src/System.Private.ServiceModel/tests/Common/Scenarios/ScenarioTestHelpers.cs @@ -210,6 +210,12 @@ public static void CloseCommunicationObjects(params ICommunicationObject[] objec { comObj.Abort(); } + catch (System.Net.WebSockets.WebSocketException) + { + // WCF Client has a bug which throws WebSocketException when the server closes the connection. + // The remote party closed the WebSocket connection without completing the close handshake. + comObj.Abort(); + } } } diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Binding/Http/NetHttpBindingTests.4.0.0.cs b/src/System.Private.ServiceModel/tests/Scenarios/Binding/Http/NetHttpBindingTests.4.0.0.cs index 6f13b3d931e..38d79931c2a 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Binding/Http/NetHttpBindingTests.4.0.0.cs +++ b/src/System.Private.ServiceModel/tests/Scenarios/Binding/Http/NetHttpBindingTests.4.0.0.cs @@ -10,7 +10,6 @@ public class Binding_Http_NetHttpBindingTests : ConditionalWcfTest { [WcfTheory] - [Condition(nameof(Skip_CoreWCFService_FailedTest))] [InlineData(NetHttpMessageEncoding.Binary)] [InlineData(NetHttpMessageEncoding.Text)] [InlineData(NetHttpMessageEncoding.Mtom)] diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Binding/Http/NetHttpsBindingTests.4.1.0.cs b/src/System.Private.ServiceModel/tests/Scenarios/Binding/Http/NetHttpsBindingTests.4.1.0.cs index 59f6e1f2f1e..ce697fead8d 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Binding/Http/NetHttpsBindingTests.4.1.0.cs +++ b/src/System.Private.ServiceModel/tests/Scenarios/Binding/Http/NetHttpsBindingTests.4.1.0.cs @@ -15,8 +15,7 @@ public class Binding_Http_NetHttpsBindingTests : ConditionalWcfTest [InlineData(NetHttpMessageEncoding.Mtom)] [Issue(3572, OS = OSID.OSX)] [Condition(nameof(Root_Certificate_Installed), - nameof(SSL_Available), - nameof(Skip_CoreWCFService_FailedTest))] + nameof(SSL_Available))] [OuterLoop] public static void DefaultCtor_NetHttps_Echo_RoundTrips_String(NetHttpMessageEncoding messageEncoding) { @@ -83,8 +82,7 @@ public static void TransportWithMessageCredential_NotSupported_NetHttps() [WcfFact] [Issue(3572, OS = OSID.OSX)] [Condition(nameof(Root_Certificate_Installed), - nameof(SSL_Available), - nameof(Skip_CoreWCFService_FailedTest))] + nameof(SSL_Available))] [OuterLoop] public static void NonDefaultCtor_NetHttps_Echo_RoundTrips_String() { diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Client/ExpectedExceptions/ExpectedExceptionTests.4.1.0.cs b/src/System.Private.ServiceModel/tests/Scenarios/Client/ExpectedExceptions/ExpectedExceptionTests.4.1.0.cs index 3878d0acac4..e5e9563ba5e 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Client/ExpectedExceptions/ExpectedExceptionTests.4.1.0.cs +++ b/src/System.Private.ServiceModel/tests/Scenarios/Client/ExpectedExceptions/ExpectedExceptionTests.4.1.0.cs @@ -328,7 +328,6 @@ public static void DuplexCallback_Throws_FaultException_ReturnsFaultedTask() } [WcfFact] - [Condition(nameof(Skip_CoreWCFService_FailedTest))] [OuterLoop] // Verify product throws MessageSecurityException when the Dns identity from the server does not match the expectation public static void TCP_ServiceCertExpired_Throw_MessageSecurityException() @@ -372,7 +371,6 @@ public static void TCP_ServiceCertExpired_Throw_MessageSecurityException() } [WcfFact] - [Condition(nameof(Skip_CoreWCFService_FailedTest))] [OuterLoop] // Verify product throws SecurityNegotiationException when the service cert is revoked public static void TCP_ServiceCertRevoked_Throw_SecurityNegotiationException() @@ -420,7 +418,6 @@ public static void TCP_ServiceCertRevoked_Throw_SecurityNegotiationException() } [WcfFact] - [Condition(nameof(Skip_CoreWCFService_FailedTest))] [OuterLoop] // Verify product throws SecurityNegotiationException when the service cert only has the ClientAuth usage public static void TCP_ServiceCertInvalidEKU_Throw_SecurityNegotiationException() diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Extensibility/WebSockets/WebSocketTests.4.1.0.cs b/src/System.Private.ServiceModel/tests/Scenarios/Extensibility/WebSockets/WebSocketTests.4.1.0.cs index d3a4fb5e6d2..6ec253ff7bb 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Extensibility/WebSockets/WebSocketTests.4.1.0.cs +++ b/src/System.Private.ServiceModel/tests/Scenarios/Extensibility/WebSockets/WebSocketTests.4.1.0.cs @@ -168,8 +168,12 @@ public static void WebSocket_Http_Duplex_Buffered(NetHttpMessageEncoding message "The logging done by the Server was not returned via the Callback."); // *** CLEANUP *** \\ - ((ICommunicationObject)client).Close(); - channelFactory.Close(); + // Close the client and channel factory if not running on localhost. CoreWCF has a bug in Close method (on Linux). + if (!ScenarioTestHelpers.IsLocalHost()) + { + ((ICommunicationObject)client).Close(); + channelFactory.Close(); + } } finally { @@ -236,8 +240,12 @@ public static void WebSocket_Http_Duplex_Buffered_KeepAlive(NetHttpMessageEncodi "The logging done by the Server was not returned via the Callback."); // *** CLEANUP *** \\ - ((ICommunicationObject)client).Close(); - channelFactory.Close(); + // Close the client and channel factory if not running on localhost. CoreWCF has a bug in Close method (on Linux). + if (!ScenarioTestHelpers.IsLocalHost()) + { + ((ICommunicationObject)client).Close(); + channelFactory.Close(); + } } finally { @@ -416,7 +424,6 @@ public static void WebSocket_Https_Duplex_Buffered(NetHttpMessageEncoding messag } [WcfTheory] - [Condition(nameof(Skip_CoreWCFService_FailedTest))] [InlineData(NetHttpMessageEncoding.Binary)] [InlineData(NetHttpMessageEncoding.Text)] [InlineData(NetHttpMessageEncoding.Mtom)] @@ -472,8 +479,12 @@ public static void WebSocket_Http_RequestReply_Streamed(NetHttpMessageEncoding m } // *** CLEANUP *** \\ - ((ICommunicationObject)client).Close(); - channelFactory.Close(); + // Close the client and channel factory if not running on localhost. CoreWCF has a bug in Close method (on Linux). + if (!ScenarioTestHelpers.IsLocalHost()) + { + ((ICommunicationObject)client).Close(); + channelFactory.Close(); + } } finally { @@ -487,7 +498,6 @@ public static void WebSocket_Http_RequestReply_Streamed(NetHttpMessageEncoding m [InlineData(NetHttpMessageEncoding.Text)] [InlineData(NetHttpMessageEncoding.Mtom)] [Issue(1438, OS = OSID.Windows_7)] // not supported on Win7 - [Condition(nameof(Skip_CoreWCFService_FailedTest))] [OuterLoop] public static void WebSocket_Http_RequestReply_Buffered(NetHttpMessageEncoding messageEncoding) { @@ -527,8 +537,12 @@ public static void WebSocket_Http_RequestReply_Buffered(NetHttpMessageEncoding m } // *** CLEANUP *** \\ - ((ICommunicationObject)client).Close(); - channelFactory.Close(); + // Close the client and channel factory if not running on localhost. CoreWCF has a bug in Close method (on Linux). + if (!ScenarioTestHelpers.IsLocalHost()) + { + ((ICommunicationObject)client).Close(); + channelFactory.Close(); + } } finally { @@ -541,7 +555,6 @@ public static void WebSocket_Http_RequestReply_Buffered(NetHttpMessageEncoding m [InlineData(NetHttpMessageEncoding.Binary)] [InlineData(NetHttpMessageEncoding.Text)] [InlineData(NetHttpMessageEncoding.Mtom)] - [Condition(nameof(Skip_CoreWCFService_FailedTest))] [Issue(1438, OS = OSID.Windows_7)] // not supported on Win7 [OuterLoop] public static void WebSocket_Http_RequestReply_Buffered_KeepAlive(NetHttpMessageEncoding messageEncoding) @@ -582,8 +595,12 @@ public static void WebSocket_Http_RequestReply_Buffered_KeepAlive(NetHttpMessage } // *** CLEANUP *** \\ - ((ICommunicationObject)client).Close(); - channelFactory.Close(); + // Close the client and channel factory if not running on localhost. CoreWCF has a bug in Close method (on Linux). + if (!ScenarioTestHelpers.IsLocalHost()) + { + ((ICommunicationObject)client).Close(); + channelFactory.Close(); + } } finally { @@ -596,8 +613,7 @@ public static void WebSocket_Http_RequestReply_Buffered_KeepAlive(NetHttpMessage [InlineData(NetHttpMessageEncoding.Binary)] [InlineData(NetHttpMessageEncoding.Text)] [InlineData(NetHttpMessageEncoding.Mtom)] - [Condition(nameof(Root_Certificate_Installed), - nameof(Skip_CoreWCFService_FailedTest))] + [Condition(nameof(Root_Certificate_Installed))] [Issue(3572, OS = OSID.OSX)] [Issue(1438, OS = OSID.Windows_7)] // not supported on Win7 [OuterLoop] @@ -638,8 +654,12 @@ public static void WebSocket_Https_RequestReply_Buffered(NetHttpMessageEncoding } // *** CLEANUP *** \\ - ((ICommunicationObject)client).Close(); - channelFactory.Close(); + // Close the client and channel factory if not running on localhost. CoreWCF has a bug in Close method (on Linux). + if (!ScenarioTestHelpers.IsLocalHost()) + { + ((ICommunicationObject)client).Close(); + channelFactory.Close(); + } } finally { @@ -652,8 +672,7 @@ public static void WebSocket_Https_RequestReply_Buffered(NetHttpMessageEncoding [InlineData(NetHttpMessageEncoding.Binary)] [InlineData(NetHttpMessageEncoding.Text)] [InlineData(NetHttpMessageEncoding.Mtom)] - [Condition(nameof(Root_Certificate_Installed), - nameof(Skip_CoreWCFService_FailedTest))] + [Condition(nameof(Root_Certificate_Installed))] [Issue(3572, OS = OSID.OSX)] [Issue(1438, OS = OSID.Windows_7)] // not supported on Win7 [OuterLoop] @@ -696,8 +715,12 @@ public static void WebSocket_Https_RequestReply_Buffered_KeepAlive(NetHttpMessag } // *** CLEANUP *** \\ - ((ICommunicationObject)client).Close(); - channelFactory.Close(); + // Close the client and channel factory if not running on localhost. CoreWCF has a bug in Close method (on Linux). + if (!ScenarioTestHelpers.IsLocalHost()) + { + ((ICommunicationObject)client).Close(); + channelFactory.Close(); + } } finally { @@ -862,8 +885,12 @@ public static void WebSocket_Http_VerifyWebSocketsUsed() Assert.True(responseFromService, String.Format("Response from the service was not expected. Expected: 'True' but got {0}", responseFromService)); // *** CLEANUP *** \\ - ((ICommunicationObject)client).Close(); - channelFactory.Close(); + // Close the client and channel factory if not running on localhost. CoreWCF has a bug in Close method (on Linux). + if (!ScenarioTestHelpers.IsLocalHost()) + { + ((ICommunicationObject)client).Close(); + channelFactory.Close(); + } } finally { diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Https/HttpsTests.4.1.1.cs b/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Https/HttpsTests.4.1.1.cs index 83fda85cadf..86f10638b6a 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Https/HttpsTests.4.1.1.cs +++ b/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Https/HttpsTests.4.1.1.cs @@ -125,8 +125,7 @@ public static void Https_SecModeTrans_CertValMode_PeerTrust_Fails_Not_In_Trusted [WcfFact] [Condition(nameof(Root_Certificate_Installed), nameof(Client_Certificate_Installed), - nameof(SSL_Available), - nameof(Skip_CoreWCFService_FailedTest))] + nameof(SSL_Available))] [Issue(1945, OS = OSID.OSX)] // OSX doesn't support the TrustedPeople certificate store [OuterLoop] // Asking for PeerOrChainTrust should succeed if the certificate is @@ -175,8 +174,7 @@ public static void Https_SecModeTrans_CertValMode_PeerOrChainTrust_Succeeds_Chai [Issue(2870, OS = OSID.OSX)] [Condition(nameof(Root_Certificate_Installed), nameof(Client_Certificate_Installed), - nameof(SSL_Available), - nameof(Skip_CoreWCFService_FailedTest))] + nameof(SSL_Available))] [OuterLoop] // Asking for ChainTrust should succeed if the certificate is // chain-trusted. diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Tcp/ClientCredentialTypeCertificateCanonicalNameTests.4.1.0.cs b/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Tcp/ClientCredentialTypeCertificateCanonicalNameTests.4.1.0.cs index 7066f485d83..4c128c4bc3b 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Tcp/ClientCredentialTypeCertificateCanonicalNameTests.4.1.0.cs +++ b/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Tcp/ClientCredentialTypeCertificateCanonicalNameTests.4.1.0.cs @@ -26,8 +26,7 @@ public class Tcp_ClientCredentialTypeCertificateCanonicalNameTests : Conditional [WcfFact] [Issue(3572, OS = OSID.OSX)] - [Condition(nameof(Root_Certificate_Installed), - nameof(Skip_CoreWCFService_FailedTest))] + [Condition(nameof(Root_Certificate_Installed))] [OuterLoop] public static void Certificate_With_CanonicalName_Localhost_Address_EchoString() { diff --git a/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Tcp/ClientCredentialTypeTests.4.1.1.cs b/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Tcp/ClientCredentialTypeTests.4.1.1.cs index bcb9182c638..107d50b476f 100644 --- a/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Tcp/ClientCredentialTypeTests.4.1.1.cs +++ b/src/System.Private.ServiceModel/tests/Scenarios/Security/TransportSecurity/Tcp/ClientCredentialTypeTests.4.1.1.cs @@ -18,8 +18,7 @@ public partial class Tcp_ClientCredentialTypeTests : ConditionalWcfTest [Condition(nameof(Root_Certificate_Installed), nameof(Client_Certificate_Installed), nameof(Peer_Certificate_Installed), - nameof(SSL_Available), - nameof(Skip_CoreWCFService_FailedTest))] + nameof(SSL_Available))] [OuterLoop] // Asking for PeerTrust alone should succeed // if the certificate is in the TrustedPeople store. For this test @@ -125,8 +124,7 @@ public static void NetTcp_SecModeTrans_CertValMode_PeerTrust_Fails_Not_In_Truste [Issue(1945, OS = OSID.OSX)] [Condition(nameof(Root_Certificate_Installed), nameof(Client_Certificate_Installed), - nameof(SSL_Available), - nameof(Skip_CoreWCFService_FailedTest))] + nameof(SSL_Available))] [OuterLoop] // Asking for PeerOrChainTrust should succeed if the certificate is // chain-trusted, even though it is not in the TrustedPeople store. diff --git a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/CoreWCF/MultiCredentialSecurityTokenManager.cs b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/CoreWCF/MultiCredentialSecurityTokenManager.cs new file mode 100644 index 00000000000..1ae31f7b810 --- /dev/null +++ b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/CoreWCF/MultiCredentialSecurityTokenManager.cs @@ -0,0 +1,55 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET +using CoreWCF.Description; +using CoreWCF.IdentityModel.Selectors; +using CoreWCF.Security; +using CoreWCF.Security.Tokens; + +namespace WcfService +{ + public class MultiCredentialSecurityTokenManager : ServiceCredentialsSecurityTokenManager + { + private readonly MultiCredentialServiceCredentials _parent; + private readonly Dictionary _map; + + public MultiCredentialSecurityTokenManager( + MultiCredentialServiceCredentials parent, + Dictionary map) + : base(parent) + { + _parent = parent; + _map = map; + } + + public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement) + { + if (tokenRequirement is RecipientServiceModelSecurityTokenRequirement recipientRequirement) + { + var uri = recipientRequirement.ListenUri?.AbsolutePath; + if (!string.IsNullOrEmpty(uri) && _map.TryGetValue(uri, out var creds)) + { + return creds.CreateSecurityTokenManager().CreateSecurityTokenProvider(tokenRequirement); + } + } + return _parent.CreateOriginalSecurityTokenManager().CreateSecurityTokenProvider(tokenRequirement); + } + + public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver) + { + if (tokenRequirement is RecipientServiceModelSecurityTokenRequirement recipientRequirement) + { + var uri = recipientRequirement.ListenUri?.AbsolutePath; + if (!string.IsNullOrEmpty(uri) && _map.TryGetValue(uri, out var creds)) + { + return creds.CreateSecurityTokenManager().CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver); + } + } + + return _parent.CreateOriginalSecurityTokenManager().CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver); + } + } +} +#endif diff --git a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/CoreWCF/MultiCredentialServiceCredentials.cs b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/CoreWCF/MultiCredentialServiceCredentials.cs new file mode 100644 index 00000000000..cb7b6759a4f --- /dev/null +++ b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/CoreWCF/MultiCredentialServiceCredentials.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET +using CoreWCF.Description; +using CoreWCF.IdentityModel.Selectors; + +namespace WcfService +{ + public class MultiCredentialServiceCredentials : ServiceCredentials + { + private readonly Dictionary _serviceCredentialsMap = new(); + + public void AddServiceCredentials(string path, ServiceCredentials credentials) + { + _serviceCredentialsMap[path] = credentials; + } + + public IReadOnlyDictionary ServiceCredentialsMap => _serviceCredentialsMap; + + public override SecurityTokenManager CreateSecurityTokenManager() + { + return new MultiCredentialSecurityTokenManager(this, _serviceCredentialsMap); + } + + internal SecurityTokenManager CreateOriginalSecurityTokenManager() + { + return base.CreateSecurityTokenManager(); + } + + protected override ServiceCredentials CloneCore() + { + var clone = new MultiCredentialServiceCredentials(); + foreach (var kvp in _serviceCredentialsMap) + { + clone.AddServiceCredentials(kvp.Key, kvp.Value.Clone()); + } + return clone; + } + } +} +#endif diff --git a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/CoreWCF/WcfServiceHost.cs b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/CoreWCF/WcfServiceHost.cs index 3df37d57284..0d9ae33516b 100644 --- a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/CoreWCF/WcfServiceHost.cs +++ b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/CoreWCF/WcfServiceHost.cs @@ -14,6 +14,7 @@ public class ServiceHost private ServiceHostBase _serviceHostBase = null; private readonly Type _serviceType; private readonly List _endpoints = new List(); + private ServiceCredentials _localCredentials = null; public ServiceHost(Type serviceType, params Uri[] baseAddresses) { @@ -50,7 +51,47 @@ public class Endpoint public Type ServiceType => _serviceHostBase != null ? _serviceHostBase.Description.ServiceType : _serviceType; - public ServiceCredentials Credentials => _serviceHostBase != null ? _serviceHostBase.Credentials : new ServiceCredentials(); + public ServiceCredentials Credentials + { + get + { + if (_localCredentials != null) + { + return _localCredentials; + } + + _localCredentials = new ServiceCredentials(); + var multiCreds = _serviceHostBase.Credentials as MultiCredentialServiceCredentials; + if (multiCreds == null) + { + throw new Exception("Credentials should have been initialized with MultiCredentialServiceCredentials"); + } + var attributes = this.GetType().GetCustomAttributes(typeof(TestServiceDefinitionAttribute), false); + if (attributes != null) + { + foreach (var attribute in attributes) + { + var basePath = "/" + ((TestServiceDefinitionAttribute)attribute).BasePath; + if (!string.IsNullOrEmpty(basePath)) + { + foreach (var endpoint in _endpoints) + { + var path = string.IsNullOrEmpty(endpoint.Address) ? basePath : basePath + "/" + endpoint.Address; + if (!multiCreds.ServiceCredentialsMap.TryGetValue(path, out var creds)) + { + multiCreds.AddServiceCredentials(path, _localCredentials); + } + else + { + _localCredentials = creds; + } + } + } + } + } + return _localCredentials; + } + } public ServiceDescription Description => _serviceHostBase != null ? _serviceHostBase.Description : new ServiceDescription(); } diff --git a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/TestDefinitionHelper.cs b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/TestDefinitionHelper.cs index 394b46d96cb..a2a768e0e05 100644 --- a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/TestDefinitionHelper.cs +++ b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/TestDefinitionHelper.cs @@ -71,6 +71,7 @@ internal static async Task StartHosts(bool useWebSocket) { bool success = true; var serviceTestHostOptionsDict = new Dictionary(); + var multiCreds = new MultiCredentialServiceCredentials(); var webHostBuilder = new WebHostBuilder() .ConfigureLogging((ILoggingBuilder logging) => @@ -256,7 +257,13 @@ internal static async Task StartHosts(bool useWebSocket) smb.HttpGetEnabled = true; } - + + var creds = serviceHostBase.Description.Behaviors.Find(); + if (creds != null) + { + serviceHostBase.Description.Behaviors.Remove(creds); + } + serviceHostBase.Description.Behaviors.Add(multiCreds); serviceHost.ApplyConfig(serviceHostBase); }); } @@ -272,8 +279,7 @@ internal static async Task StartHosts(bool useWebSocket) Console.BackgroundColor = bg; Console.ForegroundColor = fg; } - } - + } }); }); diff --git a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/TestHost.cs b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/TestHost.cs index 60ad2a8813e..28a8d45d7ca 100644 --- a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/TestHost.cs +++ b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/TestHost.cs @@ -252,8 +252,9 @@ public static X509Certificate2 CertificateFromFriendlyName(StoreName name, Store #endif foreach (X509Certificate2 cert in foundCertificates) { - // Search by serial number in Linux/MacOS - if (cert.FriendlyName == friendlyName || cert.SerialNumber == friendlyNameHash) + // Search by friendly name in Windows or by serial number in Linux/MacOS (which is the hash of the friendly name). + // Remove any leading zeros from the number string in certificate SerialNumber using TrimStart('0'). + if (cert.FriendlyName == friendlyName || cert.SerialNumber.TrimStart('0') == friendlyNameHash) { return cert; } diff --git a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/WSRequestReplyService.cs b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/WSRequestReplyService.cs index 066d83ce069..c52be5cf0dc 100644 --- a/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/WSRequestReplyService.cs +++ b/src/System.Private.ServiceModel/tools/IISHostedWcfService/App_code/WSRequestReplyService.cs @@ -13,6 +13,7 @@ using System.ServiceModel.Channels; using System.Threading; #endif +using System.Net; using System.Net.NetworkInformation; namespace WcfService @@ -43,6 +44,13 @@ public void UploadData(string data) // Access the RemoteEndpointMessageProperty RemoteEndpointMessageProperty remp = OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty; bool success = false; + IPAddress remoteIP; + + if (IPAddress.TryParse(remp.Address, out remoteIP)) + { + if (remoteIP.IsIPv4MappedToIPv6) + remoteIP = remoteIP.MapToIPv4(); + } // Get a collection of all IP addresses on the server. // Getting the addresses from the Unicast IPAddress Information collection ensures that a match @@ -51,15 +59,19 @@ public void UploadData(string data) foreach (NetworkInterface adapter in nics) { IPInterfaceProperties properties = adapter.GetIPProperties(); - UnicastIPAddressInformationCollection addressCollection = properties.UnicastAddresses; - foreach (UnicastIPAddressInformation address in addressCollection) + foreach (UnicastIPAddressInformation address in properties.UnicastAddresses) { - if (remp.Address == address.Address.ToString()) + var serverIP = address.Address; + if (serverIP.IsIPv4MappedToIPv6) + serverIP = serverIP.MapToIPv4(); + + if (remoteIP.Equals(serverIP)) { success = true; break; } } + if (success) break; } if (!success)