Wcf Basic authentication

2020-06-30 06:30发布

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?

4条回答
家丑人穷心不美
2楼-- · 2020-06-30 06:44

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

查看更多
小情绪 Triste *
3楼-- · 2020-06-30 06:46

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.

查看更多
三岁会撩人
4楼-- · 2020-06-30 06:55

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.

查看更多
Ridiculous、
5楼-- · 2020-06-30 07:03

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>
查看更多
登录 后发表回答