none
WCF security using BasicHttpBinding, SSL and UserName/Password validation RRS feed

  • Question

  • I'm using .Net 4.5. I have WCF service with SSL, and Ialso want to authenticate the service using username/password. After researching I found I have to use the combination of Transport mode and Message mode and Create a class that is derived from UserNamePasswordValidator.

    Below is my complete implementation. But doesn’t matter what I do when I browse the service via IIS or invoke via WCFTest tool, it never execute the validate method on MyValidator. Just for testing purpose I put not implemented exception hoping when I invoke the service it will throw exception. But it doesn’t.

    What im missing here

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>   
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />    
      </system.web>
      <system.serviceModel>
        <services>
          <service name="MyCompany.DocumentIntegration" behaviorConfiguration="MyServiceBehavior">
            <endpoint name="BasicHttpEndPoint" binding="basicHttpBinding" contract="MyCompany.IDocumentIntegration" bindingConfiguration="MyBasicHttpBinding" />
            <endpoint name="MexHttpEndPoint" address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
        <bindings>
          <basicHttpBinding>
            <binding name="MyBasicHttpBinding" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" receiveTimeout="00:30:00">
              <readerQuotas maxStringContentLength="2147483647" maxArrayLength="20971520" />
              <security mode="TransportWithMessageCredential">
                <message clientCredentialType="UserName"/>
              </security>
            </binding>
          </basicHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="MyServiceBehavior">
              <serviceCredentials>
                <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyCompany.MyValidator,MyCompany"/>
              </serviceCredentials>          
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />          
              <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
      </system.serviceModel>  
    </configuration>
    
    namespace MyCompany
    {
        public class MyValidator : UserNamePasswordValidator
        {
            public override void Validate(string userName, string password)
            {
                throw new NotImplementedException("Authentication is not implemented yet");
            }
        }
    }


    Wednesday, December 3, 2014 10:43 PM

Answers

  • My configuration is correct. I found that UserNamePasswordValidator will get invoked when I actually invoke the operation, Not when I browse the service in IIS.

    Thanks for your help.


    • Marked as answer by lax4u Thursday, December 4, 2014 6:19 PM
    • Edited by lax4u Thursday, December 4, 2014 6:20 PM
    Thursday, December 4, 2014 6:19 PM

All replies

  • Hi,

    For this scenario, about how to configure username/password authentication using BasicHttpBinding, you could check the following steps:

    1. Navigate to      configuration/system.serviceModel/bindings/basicHttpBinding/
    2. Add the following lines

    <binding name="usernameHttps">

       <security mode="TransportWithMessageCredential">

          <message clientCredentialType="UserName"/>                   

       </security>                   

    </binding>

    1. Change your endpoint to use the      usernameHttps binding

    <endpoint binding="basicHttpBinding"

       bindingConfiguration="usernameHttps" name="BasicHttpEndpoint" contract="WcfService4.IService1" >   

    </endpoint>

    The mexHttpBinding will need to be changed to mexHttpsBinding
    The httpGetEnabled will need to be changed to httpsGetEnabled


    1. Implement a username/password      validator by creating a class that inherits from UserNamePasswordValidator

    public class UsernNamePasswordValidator : UserNamePasswordValidator {
       
    public override void Validate(string userName, string password) {}}
    Ensure that System.IdentityModel and System.IdentityModel.Selectors are referenced.

    1. In the web.config file, goto to      configuration/system.serviceModel/behaviors/serviceBehaviors/behavior
    2. Add the following line

    <userNameAuthentication userNamePasswordValidationMode="Custom"
    customUserNamePasswordValidatorType="WcfService4.UserNamePasswordValidator, WcfService4"/>
    The first parameter is the fully qualified name of the custom username/password validator class.
    The second parameter specifies the name of the assembly that the validator is located in.

    For more detailed information, you could refer to:

    http://some-technicalstuffs.blogspot.com/2012/08/wcf-usernamepassword-authentication.html

    http://nirajrules.wordpress.com/2009/05/22/username-over-https-custombinding-with-wcf%E2%80%99s-channelfactory-interface/

    http://leastprivilege.com/2007/10/31/finally-usernames-over-transport-authentication-in-wcf/

    Regards

    Thursday, December 4, 2014 11:08 AM
    Moderator
  • if you check my configuration I posted above its exactly same as what you have said. Except I was using mexHttp instead of mexHttps

    I hosted this web service in IIS 7. Notice my validator throws exception in validate method. So when I browse the service in IIS i'm expecting "Not Implemented Exception". But instead im able to browse to the service without any problem. So it looks like the validator is not getting invoked.

    Note that the Fully Qualified Name is correct, if its not; then WCF would have thrown error. so I know its correct.


    And that also brings another question, at what time validator is actually get called? When I browse the service or when client actually call the operation?
    • Edited by lax4u Thursday, December 4, 2014 3:57 PM
    Thursday, December 4, 2014 3:52 PM
  • My configuration is correct. I found that UserNamePasswordValidator will get invoked when I actually invoke the operation, Not when I browse the service in IIS.

    Thanks for your help.


    • Marked as answer by lax4u Thursday, December 4, 2014 6:19 PM
    • Edited by lax4u Thursday, December 4, 2014 6:20 PM
    Thursday, December 4, 2014 6:19 PM