locked
All service calls issued twice (since the first call always fails with 401 - Unauthorized: Access is denied due to invalid credentials.) RRS feed

  • Question

  • Hi,

     

    we are calling WCF Data Service which is hosted under IIS 7.5 and we are using Windows Authentication and the ASP.NET Impersonation is turned on.

     

    Every time a call is issued, Fiddler reports that our application issues the request twice (first one fails with 401 and then the second one passes):

     

    FIRST REQUEST

     

    GET http://SERVER_NAME/FOO.svc/Test() HTTP/1.1

    User-Agent: Microsoft ADO.NET Data Services

    DataServiceVersion: 1.0;NetFx

    MaxDataServiceVersion: 2.0;NetFx

    Accept: application/atom+xml,application/xml

    Accept-Charset: UTF-8

    Host: SERVER_NAME

    Accept-Encoding: gzip, deflate

    Connection: Keep-Alive

     

     

    FIRST RESPONSE (with 401 error)

     

    ...

    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>

    <title>401 - Unauthorized: Access is denied due to invalid credentials.</title>

    ...

     

     

     

    SECOND REQUEST

     

    GET http://SERVER_NAME/FOO.svc/Test() HTTP/1.1

    User-Agent: Microsoft ADO.NET Data Services

    DataServiceVersion: 1.0;NetFx

    MaxDataServiceVersion: 2.0;NetFx

    Accept: application/atom+xml,application/xml

    Accept-Charset: UTF-8

    Accept-Encoding: gzip, deflate,gzip, deflate

    Authorization: Negotiate YIIGTgYGKwYB (REDUCED FOR SIZE)...

    Host: SERVER_NAME

     

     

    SECOND RESPONSE (gives us what we need)

     

     

    Is this normal? Can we do something to avoid this?

     

    Thanks,

     

    PV

    Tuesday, July 12, 2011 5:58 PM

Answers

  • This is normal, it's part of the HTTP authentication protocol, used to discover the authentication scheme the server uses, and it cannot be changed.

     

    Regards,

    PQ


    Peter Q. http://blogs.msdn.com/peter_qian
    Tuesday, July 12, 2011 6:40 PM
    Answerer

All replies

  • This is normal, it's part of the HTTP authentication protocol, used to discover the authentication scheme the server uses, and it cannot be changed.

     

    Regards,

    PQ


    Peter Q. http://blogs.msdn.com/peter_qian
    Tuesday, July 12, 2011 6:40 PM
    Answerer
  • I have assumed that, but it is nice to have it additionally confirmed - you never know if someone have invented something that would reduce amount of calls by 50%...

     

    Thank you.

     

    PV

    Tuesday, July 12, 2011 6:44 PM
  • But, is it supposed to do it every time? I have an app where I'm making several calls all in a row and this happens for each request.  It makes sense that it would do it the first time, but, after that it seems like it shouldn't. I.e. Shouldn't the client cache this and remember to send the authorization info on successive requests? I'm using Windows authentication. Could it be that it has something to due with the way NTLM works? I.e. maybe it has to do the challenge response for each request? This is really inefficient.

     

    Friday, January 6, 2012 10:48 PM
  • I tested this with a WCF Data Service as well as a normal WCF service. I found that the normal WCF service doesn't not exhibit this behavior. It looks like if you are using NTLM authentication, there are two extra requests per request. I think it's because of the challenge/response that NTLM does. With WCF Data Services, I am seeing 6 requests when I make two web service calls. If I use normal WCF with SOAP, I only see 4. I.e. it's only doing the authentication/authorization on the first call as I would expect it to. I was thinking that maybe WCF Data Services was closing the HTTP connection at the end of each request or something, but, that doesn't appear to be the case. Maybe this is just a limitation to the WCF Data Services client/proxy generated code? Also, I found that normal WCF enables gzip compression by default. WCF Data Services doesn't use gzip. I haven't yet figured out how to enable it. I'm thinking that if I could somehow get the client to the following header it would work.

    Accept-Encoding: gzip, deflate,gzip, deflate,gzip, deflate

    At any rate, the behavior that I'm seeing seems quite inefficient. Especially if you are making several requests and the requests on return a small amount of data. In that case, it's returning more data about the authorization failure than real useful data.

    I also tested it with an ASMX web service and a WCF client. The result is the same as with normal WCF. I.e. 4 requests for 2 web service calls instead of the 6 that you get with WCF Data Services.

     

    Monday, January 9, 2012 8:36 PM
  • Jon,

     

    we have a smart client app that calls WCF data

    DirectCast(e.Request, Net.HttpWebRequest).AutomaticDecompression = Net.DecompressionMethods.GZip Or Net.DecompressionMethods.Deflate


     service, and we are using compression. Two things were needed: 1) we added code to SendingRequest event, where we do the following:

     

    2) we needed to enable compression on the server (in IIS 7.5, both static and dynamic).

     As a result, amount of data coming from the server has been reduced tremendously and the performance of the app is great.

     

    PV


    • Edited by PV66 Tuesday, January 10, 2012 12:35 PM
    Tuesday, January 10, 2012 12:33 PM
  • If you are seeing the following pattern:

    • 401
    • 401
    • 200

    Then Windows Authentication is using Negotiate to authenticate: first it attempts a kerberos authentication (first 401) and if this fails it falls back to NTLM (second 401). To confirm this you can use Fiddler to look at the auth header of the HTTP messages and if you see NTLMSSP in the credential then you are using NTLM.

    If you want to authenticate via kerberos and avoid falling back to NTLM, ensure that:

    1. the service Url is trusted on the host calling the service, i.e. considered to be in the Local Intranet or Trusted Sites zone

    2. If the IIS property useAppPoolCredentials is true for the web application, an SPN needs registered against the account the mapped app pool is running as: HTTP/hostname or HTTP/hostname.domain

    NOTE: the url hostname must match the SPN, a NETBIOS hostname will not match against an SPN using the FQDN.

    3. The order of enabled providers for Windows Authentication is important, you want Negotiate before NTLM, by default it is.

    By default, IIS is configured to require authentication per call but this can be changed to a TCP session level by changing the authPersistNonNTLM setting to true for the web application.  

    At this point you should not see 401s for each WCF (SOAP) call but you will still see a 401 for each WCF Data Service call.

    The WebRequest object that is used to call the OData service has a property called PreAuthenticate which is false by default, this needs to be set to true. To get access to the WebRequest, you can subscribe to the SendingRequest event of the dbContext that is generated for you when adding a service reference to a WCF Data Service.

    Cheers,

    Stef

     


    • Edited by stefsewell Thursday, June 12, 2014 2:30 AM
    Thursday, June 12, 2014 2:28 AM