Call WCF on NetTcpBinding from anonymous website

Our project uses WCF services hosted on multiple machines. The binding used can be chosen from predefined options. One of the options is NetTcpBinding.

A website hosted in IIS with anonymous authentication is used to consume the WCF service. When the service is hosted on the same machine everything works, but when some other machine hosts the service (no domain) an exception is thrown

<Exception>
   <ExceptionType>
      System.IdentityModel.Tokens.SecurityTokenValidationException, 
      System.IdentityModel, Version=4.0.0.0, Culture=neutral, 
      PublicKeyToken=b77a5c561934e089
   </ExceptionType>
   <Message>
      The service does not allow you to log on anonymously.
   </Message>
   <StackTrace> ... </StackTrace>
   <ExceptionString> ... </ExceptionString>
</Exception>

Repro

For investigating the issue we created a small service and a website that calls the service from a button click. The interesting parts of the code is shown below.

# Create a selfsigned certificate from the command prompt.
makecert -sky exchange -r -n CN=other_machine -pe -a sha1 -len 2048 
   -ss My -sr LocalMachine c:\other_machine.cer

The other_machine.cer should be imported in Trusted People on all machines that call the WCF service.

// Main of the console app that hosts the calculate service
var machine = System.Net.Dns.GetHostName();
var address = string.Format("net.tcp://{0}:8000/calc.svc", machine);
var binding = new NetTcpBinding(SecurityMode.Transport);
var contract = typeof(ICalculate);
using (var host = new ServiceHost(typeof(CalculateService)))
{
  host.Credentials.ServiceCertificate.Certificate = 
      GetCertificateByThumbprint("thumbprint_here");
  var endpoint = host.AddServiceEndpoint(contract, binding, address);
  host.Open();
  Console.WriteLine("Listening on {0}\nPress <CR> to stop.", address);
  Console.ReadLine();
  host.Close();
}

Host the service in the console app and configure tracing to capture the exception.

// btn1_click code
var binding = new NetTcpBinding(SecurityMode.Transport);
var address = "net.tcp://other_machine:8000/calc.svc";
using (var proxy = new NetTcpService.CalculateProxy(binding, address))
{
    var r = new Random();
    var a = r.Next(1, 199);
    var b = r.Next(1, 199);
    var result = proxy.Add(a, b);
    btn1.Text = string.Format("{0} + {1} = {2}", a, b, result);
}

The website is hosted with all the defaults: DefaultAppPool, Anonymous Authentication.

After clicking the button the exception was logged to the trace file. We’ve got a repro.

Investigation

Internet is full of solutions. We’ve tried setting the credentials of the website, change application pool and allowed anonymous logons on windowsauthentication credentials. This last “solution” triggered use to look into the defaults of the NetTcpBinding. Seems the default of the clientCredentialType is Windows.

Solution

We’re not interested in the windows credentials and do want to allow anonymous access to our calculate service. The solution in the repro code above is to set the clientCredentialType to none.

var binding = new NetTcpBinding(SecurityMode.Transport);
// add this to the console app and the btn1_click
binding.Security.Transport.ClientCredentialType = 
    TcpClientCredentialType.None;

Now we can access the webservice from all clients including a website with anonymous authentication.

References

Posted in Development | Tagged , , , | Leave a comment

Goals for 2015

Last year was great for me with speaking at SDC as a high. This year I want to set some goals to get more focus on them next to my work in progress page.

More community

KROMKRATHOG2Things like writing on my blog, presenting to peers, social media presence and attending meetups.

As mentioned above the SDC was my biggest achievement of 2014. I’ve already posted a new article for their magazine.

By following challenges like Zero to hero and Blogging101/201 my blog will flourish.

Work-live balance

KROMKRATHOG3More about focus and getting things done. Work and work related time should be more efficient and effective. No more working late or attending unstructured meetings. Some inspiration from a TEDx talk on youtube.

Set a new running PR

KROMKRATHOG1I’ve been running for 3 years now. Last year was mostly about getting back from an injury. This year I want to set a new PR for any distance.

Actually I already did beat my old half marathon record last weekend. But I’ve more runs planned and will try to get an even better time or another distance PR.

Images courtesy of KROMKRATHOG / FreeDigitalPhotos.net

Posted in Uncategorized | Tagged | 1 Comment

Week 3 roundup

Last week recap and links:

Image courtesy of kanate / FreeDigitalPhotos.net

Image courtesy of kanate / FreeDigitalPhotos.net

What are your best reads this week? Leave them in the comments below.

Posted in Uncategorized | Tagged , , , , | Leave a comment

ApplicationPool creation in Metabase with Csharp

In our project we create IIS application pools from code. For this we connect to the metabase with DirectoryEntry. This is COM and the exceptions are ridiculous somewhat cryptic.

Below is code to create an Application Pool. The comments describe the HRESULT of the exception that is most likely to occur on that line of code.

var nameOfAppPool = "MyNewAppPool";
var schemaClassName = "IisApplicationPool";
var newAppPool = default(DirectoryEntry);
var applicationPools = new DirectoryEntry(
    "IIS://localhost/W3SVC/AppPools");
try
{
    // 0x80070005 > no administrative rights
    newAppPool = applicationPools.Children.Find(
        nameOfAppPool, schemaClassName);
}
catch (System.IO.DirectoryNotFoundException)
{
    // 0x8000500F > SchemaClassName is wrong, 
    //              no administrative rights
    newAppPool = applicationPools.Children.Add(
        nameOfAppPool, schemaClassName);
}

// 0x8000500C > unknown propertyvalue
// 0x80070585 > unknown index (= unknown propertyvalue)
newAppPool.Properties["ManagedRuntimeVersion"][0] = "v4.0";
// 1=Classic, 0=Integrated
newAppPool.Properties["ManagedPipelineMode"][0] = "0"; 
newAppPool.CommitChanges();

To use this code in newer versions of IIS check the IIS6 Management Compatibility in the Windows Features.

References

Posted in Development | Tagged , , , | Leave a comment

My Trello scripts are on GitHub now

I’ve had a github account since 2013. My initial use was for setting up a workflow with PhoneGab and Testflight. A colleague of mine became the mobile consultant in our company and I lost interest in this setup.

Github

Doing my talk about TDD last year made me revisit my github page. I now had a better understanding of GIT and the need of a place for my demo code. So I created the project and uploaded the code.

A post from Scott Hanselman about publishing code to keep growing, inspired me. This made me publish my TrelloScripts. I believe it is the right thing to do. Also keeps my sources “backed up” off-site.

Visit my github page here http://github.com/erictummers. Feel free to use the sources. Pull requests are welcome. Let me know what you think.

Posted in Tooling | Tagged , | 4 Comments