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