Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wcf Basic authentication

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?

like image 652
TheRealTy Avatar asked Nov 22 '11 00:11

TheRealTy


People also ask

How will you implement Basic Authentication in WCF service?

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.

How do I bypass WCF username and password?

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.

How do I add Basic Authentication to IIS?

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.

What is Basic Authentication header?

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 .


4 Answers

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>
like image 106
Trent Scholl Avatar answered Sep 17 '22 05:09

Trent Scholl


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.

like image 29
Valamas Avatar answered Sep 21 '22 05:09

Valamas


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.

like image 38
Luke Schafer Avatar answered Sep 21 '22 05:09

Luke Schafer


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

like image 29
Vedran Avatar answered Sep 20 '22 05:09

Vedran