Setting Client Credentials
Scenario: The adapter needs the client credentials for establishing connection with the target system. How can a WCF client pass these credentials to the adapter?
Remeber, the WCF-based adapter built using WCF LOB Adapter SDK is surfaced within a WCF Binding. The Adapter Consumer uses the WCF client programming model to comply with the appropriate security policy supported by the adapter. WCF LOB Adapter SDK uses the standard WCF class Client Credentials to obtain the client credentials that can be authenticated by the Target Application / System. The Client Credentials class provides properties for many types of credentials – such as client certificates, HTTP Digest, Issued Token Once set by the Adapter Consumer, these credentials can be extracted accordingly in the adapter and passed to the target application for authentication/authorization in the format the target application expects. In Beta 2, the Adapter SDK has support for the following client credential types – None, Windows, UserName and Certificate.
The type of credential support can differ per adapter.
For example, a Firebird database adapter may set the username/password obtained from the Client Credentials in the target database connection string as shown below for a Firebird database.
User=SYSDBA;Password=masterkey;Database=SampleDatabase.fdb;DataSource=localhost;Port=3050;Dialect=3;Charset=NONE;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0;
While an Oracle database adapter may warrant the adapter to set the target Oracle database credentials in the following format.
Driver={Microsoft ODBC for Oracle};Server=myServerAddress;Uid=myUsername;Pwd=myPassword;
Note: WCF Security is a massive topic and there are many articles and posts available on the internet for you to gain more knowledge on this topic.
Best Practice for Adapter Developers: Even though the support for the username/password can be added in the Connection Uri, it's recommended to use the WCF security classes to get back-end sysem credentials from the client developer.
Let’s see how the Adapter Consumer can pass credentials to the adapter in both design and runtime scenarios.
Content
1. Design Time – Using Add Adapter Service Reference Visual Studio Plug-In/Consume Adapter Service BizTalk Project Add-In
2. Run Time – Using Proxy Programming
3. Run Time – Using WCF Configuration
4. Run Time – Using Channel Programming
5. Run Time – Using BizTalk WCF Adapter
1. Design Time – Using Add Adapter Service Reference Visual Studio Plug-In/Consume Adapter Service BizTalk Project Add-In
Click on Configure button. The user can select one of the following available client credential types. The support for each client credential type will vary depending on the type of credentials the adapter supports. Note: In Beta 2, the Adapter SDK UI cannot discover the client credentials types supported by the adapter, so the Adapter Developer needs to provide the support information to the adapter consumer via other means such as documentation. Since ASDK doesn’t have this knowledge, he UI doesn’t filter the credentials types for the selected adapter and the consumer may select the types that are not accepted by the adapter.
· None
· Windows
· Username
· Certificate
Once the appropriate credentials are set, go back to the main screen and click on Connect. Underneath, the UI will use the adapter metadata WCF proxy (that uses the IMetadataRetrievalContract contract) to communicate with the adapter.
2. Run Time – Using Proxy Programming
The WCF generated client proxy has a property for Client Credentials.
The following code snippet shows how the client proxy can pass the username/password to the adapter. Following the security best practices, it is not recommended to have the username/password in clear the way I have in the sample below. The client application can query some SSO source to get the credentials and set them on the proxy.
static void Main(string[] args)
{
HelloWorldClient proxy = new HelloWorldClient("HelloWorldAdapterBinding_HelloWorld");
// specify username/password credentials
proxy.ClientCredentials.UserName.UserName = "sonua";
proxy.ClientCredentials.UserName.Password = "password";
// invoke method on the proxy
Console.WriteLine(proxy.SayHelloWorld("Bonjour"));
// close proxy
proxy.Close();
}
If the adapter supports the Windows integrated authentication, this is how the windows impersonation level can be set in the code.
static void Main(string[] args)
{
HelloWorldClient proxy = new HelloWorldClient("HelloWorldAdapterBinding_HelloWorld");
WindowsClientCredential windowsClientCredential = proxy.ClientCredentials.Windows;
Console.WriteLine("AllowedImpersonationLevel: {0}", windowsClientCredential.AllowedImpersonationLevel);
Console.WriteLine("AllowNtlm: {0}", windowsClientCredential.AllowNtlm);
Console.WriteLine("Domain: {0}", windowsClientCredential.ClientCredential.Domain);
Console.WriteLine("Username: {0}", windowsClientCredential.ClientCredential.UserName);
// change the allowed impersonation level to Delegate
windowsClientCredential.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
proxy.Close();
}
3. Run Time – Using WCF Configuration
In the client configuration file (app.config or web.config) add an <endpointBehaviours> element to include the <clientCredentials>. The complete schema reference for the endpointBehaviors can be found at this MSDN reference.
Use SvcConfigEditor to add an EndpointBehavior with <clientCredentials> extension. Alternatively you can also browse through the System.ServiceModel.Configuration.ClientCredentialsElement in the Object Browser within Visual Studio to see what sub-elements are needed.
Select File - Save to save to a configuration (.config) file.
Setting client certificate using configuration file
Add <clientCertificate> element within the <clientCredentials> endpoint behavior.
<configuration xmlns="https://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.serviceModel>
<client>
<endpoint address="hello:/"
binding="helloWorldBinding"
bindingConfiguration="HelloWorldAdapterBinding"
behaviorConfiguration = "clientEndpointCredential"
contract="HelloWorld"
name="HelloWorldAdapterBinding_HelloWorld" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="clientEndpointCredential">
< clientCredentials >
< clientCertificate
findValue="Microsoft"
storeLocation="CurrentUser"
x509FindType="FindBySubjectName"
storeName="My" />
</ clientCredentials >
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Setting windows integrated authentication using configuration file
Add the <windows> element within the <clientCredentials> endpoint behavior
<configuration xmlns="https://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.serviceModel>
. . . . .
<behaviors>
<endpointBehaviors>
<behavior name="clientEndpointCredential">
<clientCredentials>
<windows allowNtlm="false" allowedImpersonationLevel="Delegation" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
4. Run Time – Using Channel Programming
How does the channel factory know about the client credentials? Pass a BindingParameterCollection that includes Client Credentials when creating a channel factory. The following code snippet shows how to do that.
// instantiate the binding
HelloWorldAdapterBinding binding = new HelloWorldAdapterBinding();
// set the custom binding property
binding.Count = 3;
// provide client credentials to the channel
ClientCredentials clientCredentials = new ClientCredentials();
clientCredentials.UserName.UserName = "sonua";
clientCredentials.UserName.Password = "password";
BindingParameterCollection bindingParms = new BindingParameterCollection();
bindingParms.Add(clientCredentials);
// Create EndpointAddress
EndpointAddress address = new EndpointAddress("hello://");
// create channel factory using channel shape IRequestChannel
IChannelFactory<IRequestChannel> requestChannelFactory = binding.BuildChannelFactory<IRequestChannel>(bindingParms);
// open channel factory
requestChannelFactory.Open();
...
Once the channel factory is successfully opened based on the client credentials, continue to create the channel, open the channel and send/receive WCF messages to/from the channel.
5. Run Time – Using BizTalk WCF Adapter
Configure WCF-Custom transport type in the Send Port.
Setting client certificate and windows settings
Select Behavior tab. Right-click on EndpointBehavior, click on Add Extension and select clientCredentials endpoint behavior extension. This should now look very similar to the SvcConfigEditor endpoint behavior interface. Select the clientCertificate or windows based on your requirements and set the appropriate properties.
Selecting client credential behavior |
Adding Client Credentials Endpoint Behavior |
Setting username and password
Select Credentials tab. Enter the username / password or use SSO.
Note: BizTalk WCF Adapter supports importing and exporting configuration files. You can choose to configure the WCF-Custom transport type by importing a WCF configuration file that already contains the endpoint behavior or use the Send Port WCF-Custom Transport Properties UI to add the client credential endpoint behavior.
To Import or Export the configuration, select the Import/Export tab. The exported configuration (see an example below) should look very similar to setting the application configuration file in other .NET applications as shown in previous sections of this post.
<configuration>
<system.serviceModel>
<client>
<endpoint
address="hello://"
behaviorConfiguration="EndpointBehavior"
binding="helloWorldBinding"
bindingConfiguration="helloWorldBinding"
contract="BizTalk"
name="HelloWorldBinding_SendPort" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="EndpointBehavior">
<clientCredentials>
<windows allowedImpersonationLevel="Impersonation" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Comments
Anonymous
July 05, 2007
An adapter built using WCF LOB Adapter SDK can be used in variety of topologies and scenarios. FollowAnonymous
July 09, 2007
An adapter built using WCF LOB Adapter SDK can be used in variety of topologies and scenarios. FollowAnonymous
November 06, 2007
An adapter built using WCF LOB Adapter SDK can be used in variety of topologies and scenarios. FollowAnonymous
May 03, 2010
Very helpful article. Thanks so much for taking the time to write it.