none
No credentials in HTTP header with basicHttpBinding and TransportCredentialOnly security mode

    Question

  • I have the following basicHttpBinding element configured for my WCF client.

     <basicHttpBinding>
            <binding name="basicHttpOCCWS" closeTimeout="00:01:00" openTimeout="00:01:00"
                     receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                     bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                     maxBufferSize="100000000" maxBufferPoolSize="524288"
                     maxReceivedMessageSize="100000000" messageEncoding="Text"
                     textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
              <readerQuotas maxDepth="32" maxStringContentLength="8192"
                            maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
              <security mode="TransportCredentialOnly">
                <transport clientCredentialType="Basic" proxyCredentialType="Basic" realm="" />
                <message clientCredentialType="UserName" algorithmSuite="Default" />
              </security>
            </binding>
     </basicHttpBinding>

    Webservice is not WCF but is using basic HTTP authentication so it is expecting to see security credentials in the HTTP header.  Before I call the webservice, I do the following

    client.ClientCredentials.UserName.UserName = _cacledUserId;
    client.ClientCredentials.UserName.Password = _cachedPassword;

    When I try to invoke a secured method on the webservice, I get the following error:

    An authentication object was not found in the security context.

    When I use a program like Wireshack to view the HTTP messages being sent from my client, I do not see any authentication information in my header.  This is a sample message being captured.

    POST /occ600webservice/services/OCC_WS HTTP/1.1

    Content-Type: application/soap+xml; charset=utf-8; action=""

    Host: 192.54.173.130:8080

    Content-Length: 2223

    Expect: 100-continue




    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><GetSits xmlns="urn:nsEMSOCCServer"><iCacheID xmlns="">0</iCacheID><iRetrievalType xmlns="">0</iRetrievalType><query xmlns=""><Key>0</Key><Id>0</Id><EntityType>Contact</EntityType><TimeStamp>0</TimeStamp><IsActive>false</IsActive><TimeStampStart>1255093065093335700</TimeStampStart><TimeStampEnd>1255060800000000000</TimeStampEnd><UseTimeStampStart>true</UseTimeStampStart><UseTimeStampEnd>false</UseTimeStampEnd><ShouldLimitResponseCount>true</ShouldLimitResponseCount><MaxResponseCount>1000</MaxResponseCount><Direction>Outbound</Direction><TransmitTimeStart>315550800000000000</TransmitTimeStart><TransmitTimeEnd>315550800000000000</TransmitTimeEnd><ReceiveTimeStart>315550800000000000</ReceiveTimeStart><ReceiveTimeEnd>315550800000000000</ReceiveTimeEnd><MessageNumberStart>0</MessageNumberStart><MessageNumberEnd>0</MessageNumberEnd></query></GetSits></s:Body></s:Envelope>


    Now, I understand that WCF will not send authentication information unless the Webserver request for it.   If this was a secured webpage , webserver will return an HTTP 401 response.  However, this is instead a secured web service running on Apache Tomcat.   Is there a way to force WCF to ALWAYS send authentication information in the HTTP header.

    TIA

    Klaus
    Friday, October 09, 2009 2:15 PM

Answers

  • For others who run into the same problem, wrap each call to the secured webservice resource like this:

     
           var client = new WCClient(); 

           using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
                {
                    var httpRequestProperty = new HttpRequestMessageProperty();
                    httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " +
                    Convert.ToBase64String(Encoding.ASCII.GetBytes(client.ClientCredentials.UserName.UserName + ":" +
                    client.ClientCredentials.UserName.Password));
                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] =
                       httpRequestProperty;

                      client.DoSomething();
               }

    see the following links:

    http://blogs.msdn.com/drnick/archive/2008/07/08/adding-headers-to-a-call-http-version.aspx
    http://plainoldstan.blogspot.com/2008/07/avoid-http-401-roundtrip-with-adding.html
    • Marked as answer by Klaus Nji Friday, October 09, 2009 9:12 PM
    Friday, October 09, 2009 9:09 PM

All replies

  • For others who run into the same problem, wrap each call to the secured webservice resource like this:

     
           var client = new WCClient(); 

           using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
                {
                    var httpRequestProperty = new HttpRequestMessageProperty();
                    httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " +
                    Convert.ToBase64String(Encoding.ASCII.GetBytes(client.ClientCredentials.UserName.UserName + ":" +
                    client.ClientCredentials.UserName.Password));
                    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] =
                       httpRequestProperty;

                      client.DoSomething();
               }

    see the following links:

    http://blogs.msdn.com/drnick/archive/2008/07/08/adding-headers-to-a-call-http-version.aspx
    http://plainoldstan.blogspot.com/2008/07/avoid-http-401-roundtrip-with-adding.html
    • Marked as answer by Klaus Nji Friday, October 09, 2009 9:12 PM
    Friday, October 09, 2009 9:09 PM
  • I have tried this but when calling the service I get the following exception?

    The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic realm=\"localhost\"

    Pleas note that I am not using any security att all.

    Why am I gettings this exception?

    Wednesday, February 23, 2011 3:28 PM