WCF WS2007FederationHttpBinding with HTTPS

I encounter the following error when trying to connect to the WCF API, which is located behind the HTTPS proxy:

The server certificate with the name "CN = host name" did not authenticate because its fingerprint ("X") does not match the identifier specified in the endpoint identifier ("Y"). As a result, the current HTTPS request failed. Update the endpoint ID used on the client or certificate used by the server.

Where X is the fingerprint of the certificate used by the proxy server, and Y is the fingerprint of the certificate used by the service

The problem is that I managed to get the token from STS, but after that I can not make any call to the web service.

I reproduced the problem on my PC using the local SSL proxy, the certificate used on the proxy is trusted on my PC. When using HTTP, everything is fine.

I searched for a solution for several days, and I noticed this article in KB, which is close to my problem but no longer applicable (I run the sample and server in .Net 4.5): https://support.microsoft.com/en- us / kb / 2564823

What am I missing?

Here is the code:

class Program { static void Main(string[] args) { Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-us"); string serverUrl = ConfigurationManager.AppSettings["ServerURL"]; GenericXmlSecurityToken token = GetToken(serverUrl); Console.WriteLine("Token Received"); Console.WriteLine(token); TestServiceClient client = CreateClient(serverUrl, token); try { client.SearchSomething(); Console.WriteLine("SearchSomething succeeded"); } catch (Exception e) { Console.WriteLine("SearchSomething failed :" + e); } Console.ReadLine(); } private static TestServiceClient CreateClient(string serverUrl, GenericXmlSecurityToken token) { var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.Message) { MaxReceivedMessageSize = int.MaxValue, MaxBufferPoolSize = int.MaxValue }; binding.Security.Message.EstablishSecurityContext = false; binding.Security.Message.IssuedTokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"; binding.Security.Message.NegotiateServiceCredential = false; binding.ReaderQuotas.MaxDepth = int.MaxValue; binding.ReaderQuotas.MaxStringContentLength = int.MaxValue; binding.ReaderQuotas.MaxArrayLength = int.MaxValue; binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue; binding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue; var uri = new Uri(serverUrl + "Test.Service/Test.Service.svc"); var identity = new X509CertificateEndpointIdentity(new X509Certificate2(ConfigurationManager.AppSettings["ServiceCertificate"], ConfigurationManager.AppSettings["ServiceCertificatePassword"])); var client = new TestServiceClient(binding, new EndpointAddress(uri, identity)); client.ClientCredentials.SupportInteractive = false; var customBinding = new CustomBinding(); var bindingElements = binding.CreateBindingElements(); if (serverUrl.Contains("https")) { bindingElements.Remove<HttpTransportBindingElement>(); bindingElements.Add(new HttpsTransportBindingElement() { MaxReceivedMessageSize = int.MaxValue }); } customBinding.Elements.AddRange(bindingElements.ToArray()); client.Endpoint.Binding = customBinding; var clientCredentials = new SamlClientCredentials(token, client.ClientCredentials); client.Endpoint.Behaviors.Remove<ClientCredentials>(); client.Endpoint.Behaviors.Add(clientCredentials); return client; } private static GenericXmlSecurityToken GetToken(string serverUrl) { string username = ConfigurationManager.AppSettings["Username"]; string password = ConfigurationManager.AppSettings["Password"]; string identityDnsName = ConfigurationManager.AppSettings["IdentityDnsName"]; string ClientCertificate = ConfigurationManager.AppSettings["ClientCertificate"]; string ClientCertificatePassword = ConfigurationManager.AppSettings["ClientCertificatePassword"]; string ServiceCertificate = ConfigurationManager.AppSettings["ServiceCertificate"]; string ServiceCertificatePassword = ConfigurationManager.AppSettings["ServiceCertificatePassword"]; var stsUrl = serverUrl + "Security.Sts/Security.Sts.svc"; GenericXmlSecurityToken token = null; try { var customBinding = new CustomBinding(); var securityBindingElement = (SymmetricSecurityBindingElement) SecurityBindingElement.CreateMutualCertificateBindingElement(); securityBindingElement.SetKeyDerivation(true); securityBindingElement.MessageSecurityVersion = MessageSecurityVersion .WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10; securityBindingElement.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt; securityBindingElement.RequireSignatureConfirmation = false; var securityTokenParameters = new UserNameSecurityTokenParameters() { InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient, RequireDerivedKeys = false }; securityBindingElement.EndpointSupportingTokenParameters.SignedEncrypted.Add(securityTokenParameters); customBinding.Elements.Add(securityBindingElement); if (serverUrl.StartsWith("http:")) customBinding.Elements.Add(new HttpTransportBindingElement() { MaxReceivedMessageSize = int.MaxValue, MaxBufferPoolSize = int.MaxValue, MaxBufferSize = int.MaxValue }); else if (serverUrl.StartsWith("https:")) customBinding.Elements.Add(new HttpsTransportBindingElement() { MaxReceivedMessageSize = int.MaxValue, MaxBufferPoolSize = int.MaxValue, MaxBufferSize = int.MaxValue }); var stsChannelFactory = new WSTrustChannelFactory(customBinding, new EndpointAddress(new Uri(stsUrl), new DnsEndpointIdentity(identityDnsName))); stsChannelFactory.Credentials.SupportInteractive = false; stsChannelFactory.Credentials.ClientCertificate.Certificate = new X509Certificate2(ClientCertificate, ClientCertificatePassword); stsChannelFactory.Credentials.ServiceCertificate.DefaultCertificate = new X509Certificate2(ServiceCertificate, ServiceCertificatePassword); stsChannelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; stsChannelFactory.Credentials.UserName.UserName = username; stsChannelFactory.Credentials.UserName.Password = password; foreach (OperationDescription operationDescription in stsChannelFactory.Endpoint.Contract.Operations) { var operationBehavior = operationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>(); if (operationBehavior != null) operationBehavior.MaxItemsInObjectGraph = int.MaxValue; } var stsChannel = stsChannelFactory.CreateChannel(); RequestSecurityToken request = new RequestSecurityToken(); request.KeyType = "http://schemas.microsoft.com/idfx/keytype/symmetric"; request.RequestType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue"; request.TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"; token = (GenericXmlSecurityToken) stsChannel.Issue(request); return token; } catch (Exception e) { Console.WriteLine("GetToken Exception :" + e); } return token; } } internal class SamlClientCredentials : ClientCredentials { public GenericXmlSecurityToken Token { get; private set; } public SamlClientCredentials(GenericXmlSecurityToken token, ClientCredentials clientCredentials) : base(clientCredentials) { Token = token; } protected override ClientCredentials CloneCore() { return new SamlClientCredentials(Token, this); } public override SecurityTokenManager CreateSecurityTokenManager() { return new SamlSecurityTokenManager(this); } } internal class SamlSecurityTokenManager : ClientCredentialsSecurityTokenManager { private SamlClientCredentials clientCredentials; public SamlSecurityTokenManager(SamlClientCredentials clientCredentials) : base(clientCredentials) { this.clientCredentials = clientCredentials; } public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement) { if (tokenRequirement.TokenType == SecurityTokenTypes.Saml || tokenRequirement.TokenType == "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1") return new SamlSecurityTokenProvider(this.clientCredentials.Token); return base.CreateSecurityTokenProvider(tokenRequirement); } } internal class SamlSecurityTokenProvider : SecurityTokenProvider { private readonly GenericXmlSecurityToken token; public SamlSecurityTokenProvider(GenericXmlSecurityToken token) { this.token = token; } protected override SecurityToken GetTokenCore(TimeSpan timeout) { return token; } } 
+7
ssl proxy wcf
source share
1 answer

As I commented on the question: After a considerable amount of time was spent finding a solution, it seems that the WS2007FederationHttpBinding with the "Message" security mode is not intended to be used in this context due to server authentication. However, you can use the same certificate for the SSL reloader and for the service identifier.

This is a solution that I decided to keep a security model and solve my problem

0
source

All Articles