WWSAPI to WCF Interop 7: HTTP header authentication (part 2) - used in WSHttpBinding with transport security
In WCF’s standard bindings, HTTP header authentication can be used in WSHttpBinding with security mode Transport. In this security mode, the client credential type can be set to either Basic, Digest, Ntlm or Windows (Negotiate scheme) to enable HTTP header authentication. In this post, I'll use Windows client credential type. In order to communicate with such a WCF endpoint, the WWSAPI client should use a security description with two bindings: WS_SSL_TRANSPORT_SECURITY_BINDING and WS_HTTP_HEADER_AUTH_SECURITY_BINDING; and the authentication scheme should be Negotiate, as shown below:
// declare and initialize an SSL transport security binding
WS_SSL_TRANSPORT_SECURITY_BINDING sslBinding = {}; // zero out the struct
sslBinding.binding.bindingType = WS_SSL_TRANSPORT_SECURITY_BINDING_TYPE; // set the binding type
// use the default client credential – if the thread opening the channel/proxy is impersonating,
// the thread token will be used; otherwise, the process token will be used
WS_DEFAULT_WINDOWS_INTEGRATED_AUTH_CREDENTIAL defaultCred = {}; // zero out the struct
defaultCred.credential.credentialType = WS_DEFAULT_WINDOWS_INTEGRATED_AUTH_CREDENTIAL_TYPE;
// declare and initialize properties to set the authentication scheme to Negotiate
// Since the default scheme for WWSAPI header authentication is Negotiate, this property
// may be omitted.
ULONG scheme = WS_HTTP_HEADER_AUTH_SCHEME_NEGOTIATE;
WS_SECURITY_BINDING_PROPERTY headerAuthBindingProperties [1] =
{
{ WS_SECURITY_BINDING_PROPERTY_HTTP_HEADER_AUTH_SCHEME, &scheme, sizeof(scheme) }
};
// declare and initialize an header authentication security binding
WS_HTTP_HEADER_AUTH_SECURITY_BINDING headerAuthBinding = {}; // zero out the struct
headerAuthBinding.binding.bindingType = WS_HTTP_HEADER_AUTH_SECURITY_BINDING_TYPE;
headerAuthBinding.binding.properties = headerAuthBindingProperties;
headerAuthBinding.binding.propertyCount = WsCountOf(headerAuthBindingProperties);
headerAuthBinding.clientCredential = &defaultCred.credential;
// declare and initialize the array of all security bindings
WS_SECURITY_BINDING* securityBindings[2] = { &sslBinding.binding, &headerAuthBinding.binding };
// declare and initialize the security description
WS_SECURITY_DESCRIPTION securityDescription = {}; // zero out the struct
securityDescription.securityBindings = securityBindings;
securityDescription.securityBindingCount = WsCountOf(securityBindings);
Then you can create the service proxy with the security description (no channel properties are necessary for this scenario):
// Create the proxy
hr = WsCreateServiceProxy(
WS_CHANNEL_TYPE_REQUEST,
WS_HTTP_CHANNEL_BINDING,
(const WS_SECURITY_DESCRIPTION*)&securityDescription, // security description
NULL, // proxy properties
0, // proxy property count
NULL , // channel properties
0 , // channel property count
&proxy,
error);
Note: the corresponding WSHttpBinding object can be created by the following code:
WSHttpBinding binding = new WSHttpBinding(SecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
It can also be represented by the following binding element in config:
<wsHttpBinding>
<binding name="HeaderAuth">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
Comments
Anonymous
March 24, 2009
PingBack from http://blog.a-foton.ru/index.php/2009/03/25/wwsapi-to-wcf-interop-7-http-header-authentication-part-2-used-in-wshttpbinding-with-transport-security/Anonymous
March 26, 2009
In my previous post I explained how to do HTTP header authentication protected by SSL in WWSAPI. In this