Friday, May 24, 2013

Quick and Dirty ClickOnce Server

Disclaimer: This isn't necessarily the way a ClickOnce server should be set up. This is me doing the bare minimum, hacking around, just to get it up and running for someone to use quickly. If you're looking for best practice, go somewhere else.

On a server that was picked to be used as the ClickOnce server, create a folder to store the ClickOnce deployed application:

C:\ClickOnce\PrestoDashboard

Since I'm using AD authentication, I also set the security on the above folder to contain only those people that I wanted to access the app.

In the properties of the WPF app, set the location and then click Publish Now:



At this point I thought it would work, but I was getting errors when trying to access the location within my browser. So I set up a virtual directory in IIS:


I was getting an authorization error at this point, so I went into the Authentication properties of the virtual directory (screenshot above, right side) and enabled Windows Authentication.


Done:


Friday, May 17, 2013

WCF Security Issue - The target principal name is incorrect


profile for Bob Horn at Stack Overflow, Q&A for professional and enthusiast programmers
My WCF service was working when testing on my laptop. After deploying to a dev environment where the client/caller and server/WCF were on different machines, I got this error:

System.ServiceModel.Security.SecurityNegotiationException: A call to SSPI failed...System.ComponentModel.Win32Exception: The target principal name is incorrect
My situation is this:
Client (AD user) -> WCF Service (AD service account)
First, the solution. Two options:
  1. Instead of using the AD service account, use the Network Service account
  2. On the client, specify a dummy SPN
Why do these things work? Another blog post explained the situation nicely.

For option #1, the Network Service account has access to the host machine SPN. Because of this, Kerberos authentication can be used. When the AD service account is used (like my scenario), it doesn't have access to the host machine SPN, so Kerberos fails and we get the SSPI exception.

For option #2, if a dummy SPN is used, Kerberos authentication will fail, however in this case authentication will fall back to NTLM and succeed.

An example client config section, using identity, is shown here:

<identity>  <servicePrincipalName value="MySystem/Service1"/></identity>

It can also be done programmatically (second line):
var uri = new Uri(ConfigurationManager.AppSettings["serviceAddress"]);var endpointIdentity = EndpointIdentity.CreateSpnIdentity("");var endpointAddress = new EndpointAddress(uri, endpointIdentity);return _channelFactory.CreateChannel(endpointAddress);
If the client doesn't explicitly specify an identity, WCF will automatically create an identity using the host name in the Uri. If we are calling net.tcp://remotemachine1:port/MyService, the WCF client will use the machine name as the SPN, like this:

EndpointIdentity.CreateSpnIdentity("remotemachine1")

That's what will be used to call the service. When this happens, Kerberos authentication will fail, WCF will not fall back to NTLM, and we get the exception.