BizTalk and WCF Security: URLs with Port Numbers and Configuring WCF-WSHttp
A fairly common practice with WCF services that are meant purely for internal consumption within the firewall is to use a URL such as http://machineName/serviceName and not bother with creating special DNS entries for the service. And because the hosting servers often have multiple web applications running on them, using different port numbers for each web application or service is also a fairly common practice and you get URLs like http://machineName:nnnn/serviceName (where nnnn equals some port number).
When accessing these services from BizTalk, there’s usually no problem when security is not enabled on the service. However, this simple addition of a port number to the Address can be a bit problematic when configuring the Send Port to access a secure service.
In our scenario, we are calling a WCF service that uses message-based security with Windows authentication. Configuring the send port for this is a pretty straightforward activity. Selecting the Security tab in the Transport Properties allows you to configure the WCF-WSHttp port security to be message-based and use Windows authentication like this:
Note there’s nothing special or crazy here, just a simple selection of “Message” and “Windows Authentication”. We took the defaults for everything else. For a description of all these values and their meanings see http://msdn.microsoft.com/en-us/library/bb226397(v=bts.80).aspx .
Now, we are sort of set up to access the service securely, using the credentials of our BizTalk Host process. But we don’t get very far with this. Sending a message through the port generates this in a suspended message:
A message sent to adapter "WCF-WSHttp" on send port SEND_PORT_NAME with URI http://SERVER_NAME/SERVICE_NAME.svc is suspended.
Error details: System.ServiceModel.Security.SecurityNegotiationException: SOAP security negotiation with http://SERVER_NAME/SERVICE_NAME.svc for target http://SERVER_NAME/SERVICE_NAME.svc failed. See inner exception for more details. ---> System.ComponentModel.Win32Exception: Security Support Provider Interface (SSPI) authentication failed. The server may not be running in an account with identity host/SERVER_NAME. If the server is running in a service account (Network Service for example), specify the account's ServicePrincipalName as the identity in the EndpointAddress for the server. If the server is running in a user account, specify the account's UserPrincipalName as the identity in the EndpointAddress for the server.
Note the part of the message where we see host/SERVER_NAME. When Identity is not configured on the Send Port, BizTalk uses this value, based on our address, for the default. Notice, however, that it DOES NOT include the port number in its representation. Unfortunately, we can’t connect to our service this way without the port number. To solve the issue, you have to explicitly set the identity like so:
Note that our DNS value includes the port number. This will allow BizTalk to use the correct host/SERVER_NAME:portNumber notation when attempting to negotiate the security context with the WCF service. Once this is done, the send port can successfully connect and send messages to the service.