none
How to enforce username and password on a request in WCF RRS feed

  • Question

  • Good day, 

    I have a task that requires a username and password to be provided when a client makes a request to my service, so far i haven't been able to figure this out, there are many examples out there, but none of this examples have enough information that can help me achieve my goal.

    the requirement is that when a client(SOAP UI, web browser wsdl link, any other application) creates a request to my service, authentication is required before the request can be processed, the question is, what else do i need to include in my code?

    here is a my web config:

        
         <system.serviceModel>
           <services>
             <service name="namespace.servicename" behaviorConfiguration="CustomUserNamePassword" >
               <endpoint contract="namespace.interfacenane" binding="basicHttpBinding" address="basic" />           
             </service>
           </services>
        <bindings>
          <wsHttpBinding>
            <binding name="BasicAuthentication">
              <security mode="Transport">
                <transport clientCredentialType="Basic"/>
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name ="CustomUserNamePassword">
              <!-- To avoid disclosing metadata information, set the values below to false before deployment -->        
              <!-- 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="false"/>
              <serviceCredentials>
                <userNameAuthentication
                 userNamePasswordValidationMode="Custom"             customUserNamePasswordValidatorType="assembleyname.Authentication, assemblyname"/>
              </serviceCredentials>
              <serviceMetadata httpGetEnabled="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <protocolMapping>
            <add binding="basicHttpsBinding" scheme="https" />
        </protocolMapping>    
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
      </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

    and here is the authentication class

      public class Authentication : System.IdentityModel.Selectors.UserNamePasswordValidator
        {
            public override void Validate(string userName, string password)
            {
                if (userName == null || password == null)
                {
                    throw new ArgumentNullException("Username or Password is Incorrect");
                }
    
                if (!(userName == "username" && password == "password"))
                {
                    throw new Exception("Invalid Credentials");
                }
            }
        }

    If anyone has a working example, please provide it.

    Thank you in advance.

    Regards,

    Ndamu

    Thursday, November 17, 2016 5:30 AM

All replies

  • Hi Ndamu,

    Based on your code, it seems you want to achieve custom user name and password validator, am I right? If so, the security mode need to be Message or TransportWithMessageCredential.

    For your issue, you did not use the defined wsHttpBinding, you need to use the defined “BasicAuthentication” in the endpoint.

    Here is a simple configuration.

    <system.serviceModel>
      <services>
        <service name="Microsoft.ServiceModel.Samples.CalculatorService"
                 behaviorConfiguration="CalculatorServiceBehavior">
          <!-- use host/baseAddresses to configure base address provided by host -->
          <host>
            <baseAddresses>
              <add baseAddress ="http://localhost:8001/servicemodelsamples/service" />
            </baseAddresses>
          </host>
          <!-- use base address specified above, provide one endpoint -->
          <endpoint address="username"
                    binding="wsHttpBinding"
                    bindingConfiguration="Binding" 
                    contract="Microsoft.ServiceModel.Samples.ICalculator" />
        </service>
      </services>
    
      <bindings>
        <wsHttpBinding>
          <!-- username binding -->
          <binding name="Binding">
            <security mode="Message">
              <message clientCredentialType="UserName" />
            </security>
          </binding>
        </wsHttpBinding>
      </bindings>
    
      <behaviors>
        <serviceBehaviors>
          <behavior name="CalculatorServiceBehavior">
            <serviceDebug includeExceptionDetailInFaults ="true"/>
            <serviceCredentials>
              <!-- 
              The serviceCredentials behavior allows one to 
              specify a custom validator for username/password
              combinations.
              -->
              <userNameAuthentication userNamePasswordValidationMode="Custom"
                                      customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.CalculatorService+MyCustomUserNameValidator, service" />
              <!-- 
              The serviceCredentials behavior allows one to define a service certificate. A service certificate is used by a client to authenticate the service and provide message protection. You must specify a server certificate when passing username/passwords to encrypt the information as it is sent on the wire. Otherwise the username and password information would be sent as clear text. This configuration references the "localhost" certificate installed during the setup instructions.
              -->
              <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
            </serviceCredentials>
          </behavior>
        </serviceBehaviors>
      </behaviors>
    
    </system.serviceModel>
    

    You could refer the link below for more information.

    #User Name Password Validator
    https://msdn.microsoft.com/en-us/library/aa354513(v=vs.110).aspx

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, November 18, 2016 1:57 AM