Home > Mobile >  Consuming a WCF Service with custom UserNamePasswordValidator
Consuming a WCF Service with custom UserNamePasswordValidator

Time:05-16

I have a WCF Service running on my windows 2019 server on IIS. The service is to be consumed by a .Net Core library being used within a xamarin enviornment. Everything was working fine, until I wanted to add my custom UserNamePasswordValidator in order to add some security to the service.

My Web.config service section for the server looks like this

<system.serviceModel>
    <services>
        <service name="aircu_web.UpdateService" behaviorConfiguration="debug">
            <endpoint address="" name="wsHttpEndpoint" binding="wsHttpBinding" bindingConfiguration="ServiceBinding" contract="aircu_web.IUpdateService" />
        </service>
    </services>
    <bindings>
        <wsHttpBinding>
            <binding name="ServiceBinding">
                <security mode ="Message">
                    <message clientCredentialType="UserName"/>
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="production">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
            <behavior name="debug">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceCredentials>
                    <serviceCertificate storeLocation="LocalMachine" x509FindType="FindByThumbprint" findValue="84 d2 c6 d8 85 17 48 30 04 9e 12 e0 bd f4 f3 36 c1 57 b5 6e" storeName="My"/>
                    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="aircu_web.ApiKeyValidator,aircu_web"/>
                </serviceCredentials>
                
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>

when navigating to https://(mydomain)/UpdateService.svc I can see the "You have created a service" site.

When I add a service reference to my assembly, the wizard is working fine and I get all the code generated, except for the binding and the endpoint address - which is new to me. Before the change to the service, there were no additional parameters for the constructor of my service client neccessary.

When I create a client with the following code and make a call to the api

var binding = new BasicHttpsBinding();
var ep = new EndpointAddress(@"https://(my domain)/UpdateService.svc");
var svc = new AirCU.Service.UpdateServiceClient(binding, ep);

I get the exception There was no endpoint listening at https://(my domain)/UpdateService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details."

I guess somewhere there is an issue in my configuration, either client or server...

What do I need to change in order to get everything back working? :)

Thanks a lot

CodePudding user response:

Okay I figured it out myself.

Xamarin and .Net Standard do not support wsHttpEndpoints. I had to switch to a basicHttpsBinding, Xamarin does not support security mode TransportWithMessageCredential, so I had to stick with Transport only.

In the end my Web.config section looks like this:

<system.serviceModel>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <services>
        <service name="aircu_web.UpdateService" behaviorConfiguration="debug">
            <endpoint address="" name="HttpsEndpoint" binding="basicHttpsBinding" bindingConfiguration="ServiceBinding" contract="aircu_web.IUpdateService" />
        </service>
    </services>
    <bindings>
        <basicHttpsBinding>
            <binding name="ServiceBinding" maxReceivedMessageSize="1000000">
                <security mode ="Transport">
                    <message clientCredentialType="UserName"/>
                </security>
            </binding>
        </basicHttpsBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="production">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
            <behavior name="debug">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceCredentials>
                    <serviceCertificate storeLocation="LocalMachine" x509FindType="FindByThumbprint" findValue="84 d2 c6 d8 85 17 48 30 04 9e 12 e0 bd f4 f3 36 c1 57 b5 6e" storeName="My"/>
                    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="aircu_web.ApiKeyValidator,aircu_web"/>
                </serviceCredentials>
                
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>

I also had to change my client code accordingly.

private UpdateService.UpdateServiceClient GetProxy()
    {
        var binding = new BasicHttpsBinding();
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
        binding.Security.Mode = BasicHttpsSecurityMode.Transport;
        var ep = new EndpointAddress(@"https://(mydomain)/UpdateService.svc");
        var svc = new UpdateService.UpdateServiceClient(binding, ep);
        svc.ClientCredentials.UserName.UserName = "App";
        svc.ClientCredentials.UserName.Password = "****";
        return svc;
    }

I also had to move my service reference from my library project to my xamarin project, because there was some assembly mismatching of the System.ServiceModel libraries I could not figure out.

I tried installing the same nuget packages to all project, removing them, clearing bin and obj folders, re-creating the project - nothing worked. So I moved the whole service reference to the xamarin project and now it works fine. Maybe someone can tell me what went wrong there. The Error was "Type (some number) unknown...."

  • Related