I have two WCF RESTful services - the "general" service is public and has no security; the "admin" service I intend to use basic authentication over SSL. This is my server side web.config:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="general" maxReceivedMessageSize="2147483647">
<readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" />
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
<binding name="admin" maxReceivedMessageSize="2147483647">
<readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" />
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="MyNamespace.AppServices.GeneralService">
<endpoint address="" binding="webHttpBinding" contract="MyNamespace.Contracts.IGeneralService" behaviorConfiguration="web" bindingConfiguration="general" />
</service>
<service name="MyNamespace.AppServices.AdminService">
<endpoint address="" binding="webHttpBinding" contract="MyNamespace.Contracts.IAdminService" behaviorConfiguration="web" bindingConfiguration="admin" />
</service>
</services>
</system.serviceModel>
On the client side, I currently have code that looks like this:
private static IGeneralService GetGeneralChannel()
{
WebHttpBinding binding = new WebHttpBinding();
binding.Security.Mode = WebHttpSecurityMode.None;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.MaxReceivedMessageSize = Int32.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
binding.ReaderQuotas.MaxArrayLength = Int32.MaxValue;
WebChannelFactory<IGeneralService> cf = new WebChannelFactory<IGeneralService>(binding, new Uri("http://localhost:1066/GeneralService"));
IGeneralService channel = cf.CreateChannel();
return channel;
}
private static IAdminService GetAdminChannel()
{
WebHttpBinding binding = new WebHttpBinding();
binding.Security.Mode = WebHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.MaxReceivedMessageSize = Int32.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
binding.ReaderQuotas.MaxArrayLength = Int32.MaxValue;
WebChannelFactory<IAdminService> cf = new WebChannelFactory<IAdminService>(binding, new Uri("http://localhost:1066/AdminService"));
cf.Credentials.UserName.UserName = "myUserName";
cf.Credentials.UserName.Password = "myPassword";
IAdminService channel = cf.CreateChannel();
return channel;
}
The question is, since I obviously do not want to hard-code all of this configuration information, how do I need to provide it in the web.config on the client? It is pretty clear to me that the binding element needs to look pretty much the same on the client as it does on the server. However, where do I indicate the credentials that are assigned to the WebChannelFactory?
Any help and/or insight will be appreciated.
Thanks, Steve
To be able to integrate Basic Authentication with WCF REST, we have to extend the functionality of the WCF framework. The extension is divided into three steps: Find the extension point to apply behavior to all operations of the service. Create a custom authentication mechanism based on existing standards.
To configure a service to authenticate its clients using Windows Domain username and passwords use the WSHttpBinding and set its Security. Mode property to Message . In addition you must specify an X509 certificate that will be used to encrypt the username and password as they are sent from the client to the service.
TransportWithMessageCredential is a combination of both transport and message security since transport security encrypts and signs the messages as well as authenticates the service to the client and message security is used to authenticate the client to the service. Follow this answer to receive notifications.
When setting the security mode to TransportWithMessageCredential , the transport determines the actual mechanism that provides the transport-level security. For example, the HTTP protocol uses Secure Sockets Layer (SSL) over HTTP (HTTPS).
Using Windows Communication Foundation (WCF), the service can specify how a client is authenticated to the service. For example, a service can stipulate that the client be authenticated with a certificate. To determine the client credential type Retrieve metadata from the service's metadata endpoint.
To configure a WCF service to authenticate using Windows domain username and password 1 Create an instance of the WSHttpBinding, set the security mode of the binding to WSHttpSecurity.Message, set the... 2 Specify the server certificate used to encrypt the username and password information sent over the wire. This code... More ...
If you would like to see an example of configuring a similar service using a configuration file, see Message Security User Name. To configure a service to authenticate its clients using Windows Domain username and passwords use the WSHttpBinding and set its Security.Mode property to Message.
Thank you. Defines a binding element that is used to configure endpoints for Windows Communication Foundation (WCF) Web services that respond to HTTP requests instead of SOAP messages. A Boolean value that indicates whether the client accepts cookies and propagates them on future requests.
You cannot put those credentials (username and password) into web.config and have WCF read them from there. This is one of the very few features in WCF which cannot be done in config - you have to set those credentials in your code.
Of course, in your code, you can read them from e.g. a database table, or a config entry somewhere - but you have to do that yourself. WCF can't be configured to automagically read those settings from somewhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With