none
WCF - TransportWithMessageCredential Receiving 'Anonymous' Error RRS feed

  • Question

  • Hello,

    I think that I've exhausted what the Internet has to offer as far as a solution to my problem goes. What I'm trying to get working is a very simple WCF test service using the TransportWithMessageCredential mode. When I call the service from a client, I get the following error:

    System.ServiceModel.Security.MessageSecurityException: The HTTP request was forbidden with client authentication scheme 'Anonymous'. ---> System.Net.WebException: The remote server returned an error (403): Forbidden.

    Some background:

    - The service sits on an intranet server (Windows Server 2012; IIS 8.5).

    - I created a self-signed certificate (with the same FQDN as the server) and a corresponding trusted authority certificate.

    - If I use just Transport mode and basicHttpBinding, it works, but for security reasons outside of my control, credentials (username/password passed in the message) are also required.

    - Anonymous authentication is enabled for the virtual directory in IIS.

    Here is the client config:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.serviceModel>
        <client>
           <endpoint address="https://<server name>/CustomerTestPortal/WSTest.svc"
                           binding="wsHttpBinding"
                           contract="WSTestContracts.IProductData" 
           bindingConfiguration="TransportMessage" />
           <endpoint address="mex"
                           binding="mexHttpsBinding"
                           contract="IMetadataExchange" />
        </client>
        <bindings>  
          <wsHttpBinding>  
            <binding name="TransportMessage">  
     <security mode="TransportWithMessageCredential">
       <transport clientCredentialType="None"/>
       <message clientCredentialType="UserName"/>
     </security>
            </binding>  
          </wsHttpBinding>  
        </bindings>  
      </system.serviceModel>
    </configuration>

    This is the service config:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
       <system.web>
          <compilation debug="true" targetFramework="4.0" />
     <customErrors mode="Off" />
       </system.web>
      <system.serviceModel>  
        <services>  
          <service name="ProductDataWS.TestProductWS" 
                behaviorConfiguration="CustomAuthentication">  
            <endpoint address="" 
             binding="wsHttpBinding" 
     contract="WSTestContracts.IProductData" 
     bindingConfiguration="TransportMessage" />  
            <endpoint address="mex" 
             binding="mexHttpsBinding" 
     contract="IMetadataExchange" />  
          </service>  
        </services>  
        <bindings>  
          <wsHttpBinding>  
            <binding name="TransportMessage">
              <security mode="TransportWithMessageCredential">
       <transport clientCredentialType="None"/>
       <message clientCredentialType="UserName"/>
     </security>
            </binding>  
          </wsHttpBinding>  
        </bindings>  
        <behaviors>  
          <serviceBehaviors>  
            <behavior name="CustomAuthentication">
     <serviceCredentials>
       <userNameAuthentication userNamePasswordValidationMode="Custom" 
                                         customUserNamePasswordValidatorType="ProductDataWS.Validation.UserValidator, ProductDataWS" />
     </serviceCredentials>
              <serviceMetadata httpsGetEnabled="true" />  
              <serviceDebug includeExceptionDetailInFaults="true" />  
            </behavior>  
          </serviceBehaviors>  
        </behaviors>  
        <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />  
    </configuration>

    - Using a proxy created from a ClientBase, I have the following code:

             ProductClient pc = new ProductClient();
             pc.ClientCredentials.UserName.UserName = "test";
             pc.ClientCredentials.UserName.Password = "1234";
    pc.GetProductData();

    As I said above, I can verify that the self-signed certificate is not causing the problem, because if I change to just Transport mode, I can confirm that the https call is working. It's only when I change the mode to TransportWithMessageCredential that I start receiving the "Anonymous" error.

    I've also omitted the diagnostic configuration information, but the trace files that I've received are of no help. They indicate that the message was sent, but a bad HTTP response was received, and the response has the exact same "Anonymous" error information.

    Any help in solving this would be greatly appreciated! I've tried numerous different configuration settings, even though most of the documentation that I've found seems to indicate that nothing other than what I have is necessary.

    Thanks in advance,

    Tim

    Wednesday, April 19, 2017 8:51 PM

Answers

  • How did you generate client app.config? Based on your client config, it seems you write it by youself. Mex endpoint should not be added in client side. And you did not add bindingConfiguration with “TransportMessage” in client side.

    I would suggest you follow below steps.

    1.        Access https://<server name>/CustomerTestPortal/WSTest.svc from IE in client side.
    2.        If you could get wsdl, I would suggest you Add Service Reference by the feature of VS.
    3.        Try the code which is similar your current proxy code.

    For more information, I suggest you refer below link step by step.

    #How to: Use wsHttpBinding with Username Authentication and TransportWithMessageCredentials in WCF Calling from Windows Forms

    https://msdn.microsoft.com/en-us/library/ff648840.aspx


    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.

    • Marked as answer by Tim Oister Thursday, April 20, 2017 2:01 PM
    Thursday, April 20, 2017 1:57 AM

All replies

  • How did you generate client app.config? Based on your client config, it seems you write it by youself. Mex endpoint should not be added in client side. And you did not add bindingConfiguration with “TransportMessage” in client side.

    I would suggest you follow below steps.

    1.        Access https://<server name>/CustomerTestPortal/WSTest.svc from IE in client side.
    2.        If you could get wsdl, I would suggest you Add Service Reference by the feature of VS.
    3.        Try the code which is similar your current proxy code.

    For more information, I suggest you refer below link step by step.

    #How to: Use wsHttpBinding with Username Authentication and TransportWithMessageCredentials in WCF Calling from Windows Forms

    https://msdn.microsoft.com/en-us/library/ff648840.aspx


    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.

    • Marked as answer by Tim Oister Thursday, April 20, 2017 2:01 PM
    Thursday, April 20, 2017 1:57 AM
  • The mex references in the client config were the result of a bad cut/paste. Normally, I'm more comfortable creating my own service and client configs, but in this case, the Add Service Reference option fixed the problem.

    What's still somewhat confusing is that other than system-generated names (and the correct removal of the mex configuration), it doesn't look all that different than what I had hand-generated.

    It works though, and really that's all that matters!

    Thanks much!

    Tim

    Thursday, April 20, 2017 2:05 PM