Having some trouble using basic authentication with a simple test Wcf service. I am getting an exception:
The requested service, 'http://qld-tgower/test/Service.svc' could not be activated. See the > server's diagnostic trace logs for more information.
And in the trace log it shows:
The authentication schemes configured on the host ('Basic') do not allow those configured on the binding 'BasicHttpBinding' ('Anonymous'). Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly. Additionally, this may be resolved by changing the authentication schemes for this application through the IIS management tool, through the ServiceHost.Authentication.AuthenticationSchemes property, in the application configuration file at the <serviceAuthenticationManager> element, by updating the ClientCredentialType property on the binding, or by adjusting the AuthenticationScheme property on the HttpTransportBindingElement.
But what I don understand it when I us the incorrect username and password it says it IS using basic authentication?
The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic realm="qld-tgower"'.
This is my web.config details
<system.serviceModel>
<services>
<service name="WcfService"
behaviorConfiguration="Behavior">
<endpoint address="http://QLD-TGOWER/test/Service.svc"
binding="basicHttpBinding"
bindingConfiguration="httpBinding"
contract="IService" />
</service>
</services>
<diagnostics>
<endToEndTracing activityTracing="false" messageFlowTracing="true" propagateActivity="true"></endToEndTracing>
</diagnostics>
<bindings>
<basicHttpBinding>
<binding name="httpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" proxyCredentialType="Basic">
</transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
and this is my App.config
<system.serviceModel>
<diagnostics>
<endToEndTracing activityTracing="true" />
<messageLogging logMessagesAtTransportLevel="true" />
</diagnostics>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService" >
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" proxyCredentialType="Basic"></transport>
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://QLD-TGOWER/test/Service.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
name="BasicHttpBinding_IService" />
</client>
</system.serviceModel>
my test application
private static void Main(string[] args)
{
var proxy = new ServiceClient("BasicHttpBinding_IService");
var clientCredentials = proxy.ClientCredentials;
clientCredentials.UserName.UserName = "username";
clientCredentials.UserName.Password = "password";
var res = proxy.GetData(1);
Console.WriteLine(res);
Console.WriteLine("Done");
Console.ReadKey(true);
}
And my service
public class Service : IService
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
Is there something that I am missing here?
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.
In the Web Server (IIS) pane, scroll to the Role Services section, and then click Add Role Services. On the Select Role Services page of the Add Role Services Wizard, select Basic Authentication, and then click Next. On the Confirm Installation Selections page, click Install. On the Results page, click Close.
Basic authentication is a simple authentication scheme built into the HTTP protocol. The client sends HTTP requests with the Authorization header that contains the word Basic word followed by a space and a base64-encoded string username:password .
Change the name and contract of the service to include the namespace.
Also, remove the endpoint address (set it to "") and don't include proxyCredentialType in the transport tag.
End result of the web.config should look something like this
<system.serviceModel>
<services>
<service name="MyNameSpace.MyService" behaviorConfiguration="asdf">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="httpBinding" contract="MyNameSpace.IMyService" />
</service>
</services>
<diagnostics>
<endToEndTracing activityTracing="true" messageFlowTracing="true"
propagateActivity="true">
</endToEndTracing>
</diagnostics>
<bindings>
<basicHttpBinding>
<binding name="httpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="asdf">
<!-- To avoid disclosing metadata information, set the value below to
false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment to avoid
disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false"/>
</system.serviceModel>
Try for both client and server configs
<basicHttpBinding>
<binding name="BasicHttpBinding_IService">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
Install/Enable basic authentication
You may also need to install and apply basic authentication in IIS.
Goto "Programs and Features" / "Turn windows features on/off ". Enable "basic authentication" somewhere under IIS and security.
I closed and opened the IIS console and was able to enable it under authentication settings.
This of course if for a development testing and it warns you about not having an SSL certificate.
You're not allowed to use username authentication over an unsecured connection
You can secure the message by using a secure transport (e.g. SSL) or message encryption (using certificates)
I have used ClearUsernameBinding in the past to great success, but I don't recommend it in production. I used it so that I could keep all my authentication code the same without requiring SSL in dev/test environments, but having it work with SSL by changing the configuration only.
Note: that custom binding isn't perfect, and I had to change it a bit to enable certain configuration changes.
This is what solved the issue for me:
<bindings>
<basicHttpBinding>
<binding>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
For reference see: https://msdn.microsoft.com/en-gb/library/ff648505.aspx
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