This second article on integrating WCF/BizTalk Server 2006 R2 focuses on the various security options within Windows Communication Foundation and how BizTalk can consume these secure services. The first article in this series touched on the various ways to call WCF services from BizTalk Server.
The five security-based scenarios being demonstrated are:
||Client authentication uses CN=localhost|
||declarative role-based security|
Demonstrations will include multiple transports (HTTP and TCP), alternate ways to secure the service (message/transport and both) and also includes a declarative, role-based security model. The example WCF services built for this article all share a common service contract/interface, but separate services/hosts were built for each scenario so that settings could be persisted for each scenario.
Scenario #1 - Message Based Security (Windows)
Let's start with an existing WCF service which demands message based security. If one doesn't explicitly flip the security flag to “None”, this is the default value for any .NET Framework 3.0 WCF service.
Within the BizTalk Server 2006 R2 project, the first thing to do is add a reference to the WCF service. This is not done via “Add web reference”, but rather, using the “Add Generated Items” wizard.
Next choose where to retrieve the service metadata. In most cases, one would probably choose the Metadata Exchange option where one can point to either a URL + WSDL or a MEX endpoint.
However, there are certainly cases where a live service yet does not yet exist, and instead only the static WSDL file and schema exist. Choosing a non-MEX/WSDL endpoint in the wizard, allows selection of the WSDL and XSD file explicitly. This demonstrated used the "svcutil.exe /t:metadata" command to generate metadata files from a live service.
The result of this wizard is an orchestration file, binding files, and the schemas. One can certainly build scenarios without this wizard, but for simplicity sake, let’s continue to use these auto-generated resources.
Instead of using the auto-generated orchestration to house the process logic, let’s simply use the bits in that orchestration inside a separate orchestration. This way, if one later has to re-run the generation wizards, there no concerns about overwriting or messing with core process logic.
The primary orchestration receives a simple “employee” message and calls out to the secure WCF service. Once the primary flow shapes are added to the orchestration, a new configured port is added which reused the existing port type embedded in our auto-generated orchestration.
So the basic orchestration now looks like this. The last “Log Result” Expression shape simply writes a trace statement which indicates that the orchestration called the service successfully.
After the BizTalk project is deployed, a physical send port must be added to call the actual WCF service. To do so manually, one would create a brand new request/response port and chose the BizTalk WCF adapter that matched the binding of the service. Instead, let’s use the binding file that was generated by the “Add Generated Items” wizard. There are actually two binding files created by that wizard – one which uses the BizTalk adapter matching the binding of the service (in this case, WS-HTTP), and another “custom” binding which utilizes the “WCF-Custom” adapter. Both of these are used in this article. For now, the WCF-WSHttp binding is sufficient for creating the necessary physical send port.
In reviewing the adapter settings, they should be the same as those configured via a service reference in a standard .NET project (class library, etc). The adapter simply puts a BizTalk-looking UI on the standard WCF binding parameters.
Notice the reference-only “Endpoint Identity” section. Remember that this doesn’t SET the identity, but rather, shows what the service expects. Changing this value doesn’t impact the service call itself. A later demonstration will show how to change the service endpoint identity.
The “Security” tab of the WCF-WSHttp adapter shows the same settings that one would find when consuming this WCF service from any client.
After starting the BizTalk components (orchestration/send port/receive location), and then starting the WCF host (don’t forget that step!), a file can be dropped and the Debug window will display the success messages written by both the service and the orchestration.
The current service user is identified, and the orchestration confirms a successful transmission. If one wants to see a chattier version of what happened, turn tracing on in the WCF service so that a log file is written when the service is called.
This is done by adding a new "listener" under "diagnostics" and creating the necessary trace type and output location. Now if the service is called again, a file named app_tracelog.svclog is created on the server. This file is read via the Service Trace Viewer tool that comes with the .NET Framework 3.0.
Notice that my single call to the first service (message-based security) shows LOTS of traffic back and forth. There are numerous security handshake messages traveling back and forth via the WCF infrastructure. Via this tool, the secured message data is visible (in the picture above see the CipherValue), and also in the clear, after the service has decrypted the value. The Service Trace Viewer is a nice way to see an overview of the service transmission.
Back to the security context, note that the Windows account passed to the service is the account of the host instance. This was seen above in the DebugViewer trace statement where the service caller was identified (“current user is …”). One can prove that the host instance account is the one used by the service by putting this send port into a host instance running as a different account and re-running our scenario. The “SecureWCFServiceHost” BizTalk Server Host runs under a “WCFUser” account and as can be seen below, has been added as a valid send handler for the WCF-WSHttp BizTalk adapter.
Rerunning the original scenario produces the following result:
Notice that the current user is now the Windows account of the new BizTalk host instance.
Scenario #2 - Transport Security
Now let’s try the “transport” security scenario. Prior to building the service, one has to have a security certificate installed on the machine. So, this solution used the “makecert” tool and executed the following command:
makecert -r -pe -n "CN=localhost" -ss my -sr localMachine -sky exchange
This created a usable certificate in the "my user" certificate store. It was manually added it to my machine’s certificate store as well. Finally, the certificate needs to be registered with IIS to support https communication.
Inside the WCF service configuration file, a service behavior (“serviceCredentials”) was added where the certificate required for the client to authenticate themselves was specified.
This means that the caller must explicitly have this certificate in order to be allowed to call the service. To tell my WCF service to force client authentication via certificates, the service must reference this binding:
Within the BizTalk project, once again the “Add Generated Items” wizard was used and and pointed to the https endpoint of the transport-secured service. However this time, when it was completed, everything but the bindings was deleted. Because each service uses the same contract (as mentioned at the top of the article), the message formats (contract) for each service scenario is identical, and thus the schema/orchestration from the previous scenario is reusable. In the orchestration I add another service call, reusing the same port type as in the prior example.
After deploying, the newest binding file was imported to get the necessary WCF send port. Notice the fact that now “Transport” security is set, and client certificate thumbprint was chosen from the user's certificate store.
Triggering the service yields the same successful "trace" message to the log file.
Scenario #3 - Message Based (Windows) and Transport Security
Next, let’s utilize both payload AND channel security. Once again, the “Add Generated Items” wizard was used against the service and the sought-after send port binding files were discharged.
In this WCF service, there is no client certificate required for authentication, so the BizTalk WCF send port configuration (using TransportWithMessageCredential security mode) only has the message security settings explicitly set.
As expected, once the service is called over the HTTPS channel, a confirmation was received from both the service and BizTalk orchestration that the service call was successful.
Scenario #4 - Message Based Security (Username)
What if one doesn't care for the standard “Windows” based message security? That is, what the service owner wants more control over the credentials being passed to the service?
If the WCF service requires “username” level message security, BizTalk works fine with that as well. The “username” mode works much like HTTP basic authentication. However, WCF forces you to utilize a secure channel (HTTPS) so that the credentials aren’t passed in the clear. In this scenario, the username and password map back to Windows accounts, vs. writing a custom database-backed repository.
The BizTalk WCF send port for this configuration looks like this:
Notice that TransportWithMessageCredential is set, indicating that the HTTPS channel is being used. The “message client credential type” is set to “Username”, which then allows the user to edit the “user name credentials” value. Notice that the BizTalk SSO store can be used to map to an account if hardcoding a value was undesirable.
Scenario #5 - Message Based (Windows), Declarative Security
Finally, what if the WCF service had a method-level declarative security model applied? That is, what if the WCF service operation was written like this:
[PrincipalPermission(SecurityAction.Demand, Role= @"WCFAppUsers")]
string IWorkforce.GetEmployeeStatus(string workforceId)
In this case, the service is requiring that the caller is in the Windows Group named “WCFAppUsers.” Any call to the service by a user NOT in this group will generate a security exception. This service has message-level security applied with a Windows client credential and also uses the TCP protocol for binding.
This final WCF service call ws inserted into the orchestration after adding the necessary binding files to the BizTalk project via the “Add Generate Items” wizard. Now the single orchestration calls all five services, each with different security configurations:
For this particular scenario, the auto-generated “custom” binding file was used for the send port. What did that do? The WCF-Custom BizTalk adapter exposes many more WCF configuration flags and settings than the standard WCF protocol adapters.
Here one can add custom behaviors to the service which are otherwise unavailable in the other WCF adapters. This is a primary reason to use the WCF-Custom adapter over the other BizTalk WCF adapters. There is also a “credentials” tab exposed here, but the values entered in this tab are only applied if a “username” security model is chosen. Otherwise, the Windows account operating the host instance is the account of record. In this case, the“SecureWCFServiceHost” host instance, which uses a Windows account in the “WCFAppUsers” group demanded by my service, is used by this service.
After dropping my file one last time, I saw all five services called, and (highlighted here) all five confirmation messages from my orchestration.
WCF offers a wide range of security configurations supporting both message level and transport level schemes. In some cases you may be the author of both the service AND the BizTalk components, but if you are not the WCF service creator, you can still be fairly confident that BizTalk Server 2006 R2 can consume most any security scheme put in place for the service.
We’ve seen here how to utilize basic Windows authentication, username authentication, certificate authentication for HTTPS transport, declarative code-based security, as well as how to work with auto-generated files from the BizTalk wizards.
Once this entire BizTalk+WCF series is complete, I will make the entire source code available.
Questions, comments or corrections? Go ahead and leave a comment on my blog post about this article.
You can read more about BizTalk, SOA and enterprise architecture on my blog at http://seroter.wordpress.com.