Self hosted WCF service in a managed app with a certificate reporting and error “HTTP request forbidden with client authentication scheme Anonymous”

I have a Windows service that self hosts a WCF service for clients to connect to, current it using unsecure HTTP connection. I have bought an SSL certificate from a trusted CA that I already use to secure my web application successfully.

I want to secure the Windows service so that the host server and clients can install the certificate and only these clients would be authenticated to connect to the WCF service.

As a test I have created a simple Host/Client console application to test the security using the certificate.

Currently the service is showing as secure when I navigate to the baseline address, but when the client attempts to connect to the service and use one the calls, I get an error in the client application stating “The HTTP request was forbidden with client authentication scheme ‘Anonymous’.”

Right now I have the client set up to present the certificate to the WCF service defined in its app.config, so it shouldn’t be trying to connect anonymously. I’ve tried changing the authentication settings in ISS, but obviously that wouldn’t work as the WCF is not hosted in IIS, but as a Windows service and in this test, it is just a console application.

I have the certificate installed on both the server and client “Local Computer – Trusted Root Certification Authorities” and “Local Computer – Personal” stores. I have even tried putting it in the “Trusted People” store.

Below you can see the C# code and the app.configs for the Host/Client.

Host Program.cs (I have changed the actual URL to testendpoint for security reasons):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>using System;
using System.ServiceModel;
namespace SimplifiedHostService
{
[ServiceContract]
public interface ISimplifiedHostServiceContract
{
[OperationContract]
string SimplifiedHostServiceMethod(string input);
}
public class SimplifiedHostService : ISimplifiedHostServiceContract
{
public string SimplifiedHostServiceMethod(string input)
{
return "You said: " + input;
}
}
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("https://testendpoint:8000/SimplifiedHostService");
// Create a ServiceHost instance
using (ServiceHost host = new ServiceHost(typeof(SimplifiedHostService), baseAddress))
{
try
{
host.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();
host.Close();
}
catch (CommunicationException ex)
{
Console.WriteLine("An exception occurred: {0}", ex.Message);
host.Abort();
}
}
}
}
}
</code>
<code>using System; using System.ServiceModel; namespace SimplifiedHostService { [ServiceContract] public interface ISimplifiedHostServiceContract { [OperationContract] string SimplifiedHostServiceMethod(string input); } public class SimplifiedHostService : ISimplifiedHostServiceContract { public string SimplifiedHostServiceMethod(string input) { return "You said: " + input; } } class Program { static void Main(string[] args) { Uri baseAddress = new Uri("https://testendpoint:8000/SimplifiedHostService"); // Create a ServiceHost instance using (ServiceHost host = new ServiceHost(typeof(SimplifiedHostService), baseAddress)) { try { host.Open(); Console.WriteLine("The service is ready."); Console.WriteLine("Press <Enter> to stop the service."); Console.ReadLine(); host.Close(); } catch (CommunicationException ex) { Console.WriteLine("An exception occurred: {0}", ex.Message); host.Abort(); } } } } } </code>
using System;
using System.ServiceModel;

namespace SimplifiedHostService
{
    [ServiceContract]
    public interface ISimplifiedHostServiceContract
    {
        [OperationContract]
        string SimplifiedHostServiceMethod(string input);
    }

    public class SimplifiedHostService : ISimplifiedHostServiceContract
    {
        public string SimplifiedHostServiceMethod(string input)
        {
            return "You said: " + input;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Uri baseAddress = new Uri("https://testendpoint:8000/SimplifiedHostService");

            // Create a ServiceHost instance
            using (ServiceHost host = new ServiceHost(typeof(SimplifiedHostService), baseAddress))
            {
                try
                {
                    host.Open();
                    Console.WriteLine("The service is ready.");
                    Console.WriteLine("Press <Enter> to stop the service.");
                    Console.ReadLine();

                    host.Close();
                }
                catch (CommunicationException ex)
                {
                    Console.WriteLine("An exception occurred: {0}", ex.Message);
                    host.Abort();
                }
            }
        }
    }
}

Host app.config:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><configuration>
<system.serviceModel>
<services>
<service name="SimplifiedHostService.SimplifiedHostService">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="secureBinding"
contract="SimplifiedHostService.ISimplifiedHostServiceContract" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate storeLocation="LocalMachine"
storeName="Root"
x509FindType="FindBySubjectName"
findValue="TestCertificateSubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
</code>
<code><configuration> <system.serviceModel> <services> <service name="SimplifiedHostService.SimplifiedHostService"> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="secureBinding" contract="SimplifiedHostService.ISimplifiedHostServiceContract" /> </service> </services> <bindings> <basicHttpBinding> <binding name="secureBinding"> <security mode="Transport"> <transport clientCredentialType="Certificate" /> </security> </binding> </basicHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpsGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> <serviceCredentials> <serviceCertificate storeLocation="LocalMachine" storeName="Root" x509FindType="FindBySubjectName" findValue="TestCertificateSubjectName" /> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration> </code>
<configuration>
    <system.serviceModel>
        <services>
            <service name="SimplifiedHostService.SimplifiedHostService">
                <endpoint address=""
                          binding="basicHttpBinding"
                          bindingConfiguration="secureBinding"
                          contract="SimplifiedHostService.ISimplifiedHostServiceContract" />
            </service>
        </services>
        <bindings>
            <basicHttpBinding>
                <binding name="secureBinding">
                    <security mode="Transport">
                        <transport clientCredentialType="Certificate" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior>
                    <serviceMetadata httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                    <serviceCredentials>
                        <serviceCertificate storeLocation="LocalMachine"
                                            storeName="Root"
                                            x509FindType="FindBySubjectName"
                                            findValue="TestCertificateSubjectName" />
                    </serviceCredentials>
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>

Client Program.cs

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// Shared service contract interface (copied from server project)
using System.ServiceModel;
using System;
namespace SimplifiedHostService
{
[ServiceContract]
public interface ISimplifiedHostServiceContract
{
[OperationContract]
string SimplifiedHostServiceMethod(string input);
}
}
namespace WCFClient
{
class Program
{
static void Main(string[] args)
{
// Create a channel to the service using the shared service contract interface
var factory = new ChannelFactory<SimplifiedHostService.ISimplifiedHostServiceContract>("SimplifiedHostService");
SimplifiedHostService.ISimplifiedHostServiceContract channel = null;
try
{
// Create a channel to the service
channel = factory.CreateChannel();
// Call the service method
string result = channel.SimplifiedHostServiceMethod("Hello from client");
// Display the result
Console.WriteLine("Result from service: " + result);
}
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
finally
{
// Close the channel factory and the channel
if (channel != null && channel is ICommunicationObject)
{
((ICommunicationObject)channel).Close();
}
factory.Close();
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
</code>
<code>// Shared service contract interface (copied from server project) using System.ServiceModel; using System; namespace SimplifiedHostService { [ServiceContract] public interface ISimplifiedHostServiceContract { [OperationContract] string SimplifiedHostServiceMethod(string input); } } namespace WCFClient { class Program { static void Main(string[] args) { // Create a channel to the service using the shared service contract interface var factory = new ChannelFactory<SimplifiedHostService.ISimplifiedHostServiceContract>("SimplifiedHostService"); SimplifiedHostService.ISimplifiedHostServiceContract channel = null; try { // Create a channel to the service channel = factory.CreateChannel(); // Call the service method string result = channel.SimplifiedHostServiceMethod("Hello from client"); // Display the result Console.WriteLine("Result from service: " + result); } catch (Exception ex) { Console.WriteLine("An error occurred: " + ex.Message); } finally { // Close the channel factory and the channel if (channel != null && channel is ICommunicationObject) { ((ICommunicationObject)channel).Close(); } factory.Close(); } Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } } } </code>
// Shared service contract interface (copied from server project)
using System.ServiceModel;
using System;
 
namespace SimplifiedHostService
{
    [ServiceContract]
    public interface ISimplifiedHostServiceContract
    {
        [OperationContract]
        string SimplifiedHostServiceMethod(string input);
    }
}
 
namespace WCFClient
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a channel to the service using the shared service contract interface
            var factory = new ChannelFactory<SimplifiedHostService.ISimplifiedHostServiceContract>("SimplifiedHostService");
 
            SimplifiedHostService.ISimplifiedHostServiceContract channel = null;
            try
            {
                // Create a channel to the service
                channel = factory.CreateChannel();
                // Call the service method
                string result = channel.SimplifiedHostServiceMethod("Hello from client");
 
                // Display the result
                Console.WriteLine("Result from service: " + result);
            }
            catch (Exception ex)
            {
                Console.WriteLine("An error occurred: " + ex.Message);
            }
            finally
            {
                // Close the channel factory and the channel
                if (channel != null && channel is ICommunicationObject)
                {
                    ((ICommunicationObject)channel).Close();
                }
 
                factory.Close();
            }
 
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

Client app.config:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code><configuration>
<system.serviceModel>
<client>
<endpoint name="SimplifiedHostService"
address="https://testendpoint:8000/SimplifiedHostService"
binding="basicHttpBinding"
bindingConfiguration="secureBinding"
behaviorConfiguration="test"
contract="SimplifiedHostService.ISimplifiedHostServiceContract" />
</client>
<bindings>
<basicHttpBinding>
<binding name="secureBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="test">
<clientCredentials>
<!-- Specify the client certificate -->
<clientCertificate storeLocation="LocalMachine"
storeName="Root"
findValue="TestCertificateSubjectName"
x509FindType="FindBySubjectName"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
</code>
<code><configuration> <system.serviceModel> <client> <endpoint name="SimplifiedHostService" address="https://testendpoint:8000/SimplifiedHostService" binding="basicHttpBinding" bindingConfiguration="secureBinding" behaviorConfiguration="test" contract="SimplifiedHostService.ISimplifiedHostServiceContract" /> </client> <bindings> <basicHttpBinding> <binding name="secureBinding"> <security mode="Transport"> <transport clientCredentialType="Certificate" /> </security> </binding> </basicHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="test"> <clientCredentials> <!-- Specify the client certificate --> <clientCertificate storeLocation="LocalMachine" storeName="Root" findValue="TestCertificateSubjectName" x509FindType="FindBySubjectName"/> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel> </configuration> </code>
<configuration>
    <system.serviceModel>
    <client>
        <endpoint name="SimplifiedHostService"
             address="https://testendpoint:8000/SimplifiedHostService"
             binding="basicHttpBinding"
             bindingConfiguration="secureBinding"
         behaviorConfiguration="test"
             contract="SimplifiedHostService.ISimplifiedHostServiceContract" />
        </client>
        <bindings>
        <basicHttpBinding>
        <binding name="secureBinding">
             <security mode="Transport">
             <transport clientCredentialType="Certificate" />
                 </security>
        </binding>
         </basicHttpBinding>
        </bindings>
        <behaviors>
        <endpointBehaviors>
        <behavior name="test">
             <clientCredentials>
            <!-- Specify the client certificate -->
            <clientCertificate storeLocation="LocalMachine"
                               storeName="Root"
                               findValue="TestCertificateSubjectName"
                               x509FindType="FindBySubjectName"/>
            </clientCredentials>
        </behavior>
        </endpointBehaviors>
    </behaviors>
     </system.serviceModel>
</configuration>

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật