简体   繁体   中英

WCF UserName & Password validation using wshttpbinding notworking

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.

在此处输入图片说明

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

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.

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. 在此处输入图片说明
The service address would be https://xxxx: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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM