0

I am new to WCF Service authentication, I was trying to achieve wcfauthentication using wshttpbinding. but i am getting below exception.

Could not find a base address that matches scheme https for the endpoint with binding WSHttpBinding. Registered base address schemes are [http].

Web.Config:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>  
    <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttp">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="WCFAuth.Service1" behaviorConfiguration="wsHttpBehavior">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttp" contract="WCFAuth.IService1">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:64765/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="wsHttpBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFAuth.ServiceAuthanticator, WCFAuth"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>

Service Authentication class:

using System;
using System.Collections.Generic;
using System.IdentityModel.Selectors;
using System.Linq;
using System.ServiceModel;
using System.Web;

namespace WCFAuth
{
    public class ServiceAuthanticator : UserNamePasswordValidator
    {

        public override void Validate(string userName, string password)
        {
            string AppUserName = "ABC";
            string AppPwd = "abc";
            try
            {
                if (userName.ToLower() != AppUserName.ToLower() && password != AppPwd)
                {                        
                    throw new FaultException("Unknown Username or Incorrect Password");
                }
            }
            catch (Exception ex)
            {                    
                throw new FaultException("Unknown Username or Incorrect Password");
            }
        }
    }
}

Client Side config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <!--<binding name="base" />-->
              <binding name="base">
                <security mode="TransportCredentialOnly">
                  <transport clientCredentialType="Basic"/>
                </security>
              </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:64765/Service1.svc" binding="basicHttpBinding"
                bindingConfiguration="base" contract="WCFAuth.IService1" name="base" />
        </client>
    </system.serviceModel>
</configuration>

Consumer:

class Program
    {
        static void Main(string[] args)
        {
            try
            {
                WCFAuth.Service1Client client = new WCFAuth.Service1Client();                
                client.ClientCredentials.UserName.UserName = "test";
                client.ClientCredentials.UserName.Password = "test";                
                var temp = client.GetData(1);
                Console.WriteLine(temp);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.ReadKey();
        }
    }

I am getting attached exception when i try to browser svc file.

enter image description here

Can someone correct me, where i am committing mistake, thanks in advance.

Vicky S
  • 762
  • 4
  • 16

2 Answers2

1

The problem here is that you are using a WSHttpBinding with Transport Security, but the base address you set is http. It is not possible to work with http here, because you are sending credentials over the wire.

Either change it to https, or create a second binding configuration for development purposes. One with Transport Security (https), and a second without (http).

Also make sure that your clients binding matches the binding from your server.

Marc
  • 3,905
  • 4
  • 21
  • 37
  • Than you I have followed your suggestion i getting attached exception: System.ServiceModel.ServiceActivationException: The service '/Service1.svc' cannot be activated due to an exception during compilation. The exception message is: Cannot find the X.509 certificate using the following search criteria: StoreName 'My', StoreLocation 'LocalMachine', FindType 'FindByThumbprint', FindValue '869f82bd848519ff8f35cbb6b667b34274c8dcfe' – Vicky S May 06 '19 at 04:40
0

As Marc mentioned, we are supposed to provide a certificate when hosting the service. there might be something amiss during the process of hosting the service.
Here is a reference configuration, wish it is useful to you.

<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttp">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="WCFAuth.Service1" behaviorConfiguration="wsHttpBehavior">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttp" contract="WCFAuth.IService1">
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="wsHttpBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFAuth.ServiceAuthanticator, WCFAuth"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Then we should add a https binding in IIS Site Bindings module. enter image description here
The service address would be https://x.x.x.x:8865/Service1.svc
One thing must be noted that we should trust the service certificate when we call the service by adding service reference.

ServicePointManager.ServerCertificateValidationCallback += delegate
              {
                  return true;
              };
            ServiceReference2.Service1Client client = new ServiceReference2.Service1Client();
            client.ClientCredentials.UserName.UserName = "jack";
            client.ClientCredentials.UserName.Password = "123456";

Besides, if we use SecurityMode.Message, we are supposed to provide a certificate in code snippets.

  <serviceCredentials>
            <serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="869f82bd848519ff8f35cbb6b667b34274c8dcfe"/>
            <userNameAuthentication customUserNamePasswordValidatorType="WcfService1.CustUserNamePasswordVal,WcfService1" userNamePasswordValidationMode="Custom"/>
          </serviceCredentials>

Feel free to let me know if there is anything I can help with.

Abraham Qian
  • 7,117
  • 1
  • 8
  • 22
  • I am getting attached exception: System.ServiceModel.ServiceActivationException: The service '/Service1.svc' cannot be activated due to an exception during compilation. The exception message is: Cannot find the X.509 certificate using the following search criteria: StoreName 'My', StoreLocation 'LocalMachine', FindType 'FindByThumbprint', FindValue '869f82bd848519ff8f35cbb6b667b34274c8dcfe' – Vicky S May 06 '19 at 04:39
  • The certificate you provided is supposed to have been installed in the Local machine certificate store. We could use Certlm.msc command to check the installed certificate. Ensure you the certificate whose thumbprint is the specific value has installed in the corresponding location, or use the other installed certificate. – Abraham Qian May 06 '19 at 05:28