WCF REST Service Trying To Authenticate TWICE!

Discussion in 'ASP.NET WebServices' started by TheAggie, Apr 1, 2010.

  1. Ok, if someone could shed some light on this for me, I would greatly appreciate it. So here we go. I had a rest service running fine the other day but after I accidentally overwrote the web.config all hell broke loose. I've spent the past day and a half trying to sort things out but I can't seem to figure out what is missing or misplaced.

    So, I've designed this service around WCF Rest Contrib (http://wcfrestcontrib.codeplex.com)'s authentication process. Now, I can get this working fine on my localhost w/ the current web.config (minus the endpoint entry) but once I upload it to discountasp and select "basic authorization" in the ISS7 Manager, it appears that I'm getting authenticated twice! Once using my discount asp.net user/pass and then the next time using the application user/pass. Unfortunately I only provide one set of credentials and don't want to hard code my discountasp account info into the app. Like I said before, this worked fine a few days ago. Anyway. here is my web.config as it is now:

    Code:
    <?xml version="1.0"?>
    <configuration>
      <connectionStrings>
        <add name="SQL2008_ConnectionString" connectionString="Data Source=sql2k8xx.discountasp.net;Initial Catalog=SQL2008_xx;Persist Security Info=True;User ID=SQL2008_xx_user;Password=myPass"
          providerName="System.Data.SqlClient" />
      </connectionStrings>
      <system.web>
        <httpRuntime maxRequestLength="204800" executionTimeout="3600"/>
        <compilation debug="true">
          <assemblies>
            <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
            <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
          </assemblies>
        </compilation>
        
        <httpModules>
          <add name="ServiceAnonymityModule" type="WcfRestContrib.Web.ServiceAnonymityModule, WcfRestContrib"/>
        </httpModules>
      </system.web>
      
      <system.codedom>
        <compilers>
          <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
            <providerOption name="CompilerVersion" value="v3.5"/>
            <providerOption name="WarnAsError" value="false"/>
          </compiler>
        </compilers>
      </system.codedom>
    
      <system.webServer>
        <validation validateIntegratedModeConfiguration="false"/>
        <modules>
          <remove name="ServiceAnonymityModule"/>
          <add name="ServiceAnonymityModule" type="WcfRestContrib.Web.ServiceAnonymityModule, WcfRestContrib"/>
        </modules>
        <handlers>
          <remove name="WebServiceHandlerFactory-Integrated"/>
        </handlers>
      </system.webServer>
      
      <system.diagnostics>
      <trace autoflush="true" />
      </system.diagnostics>
      
      <system.serviceModel>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="false">
          <baseAddressPrefixFilters>
            <add prefix="http://www.mydomain.com/myServiceBaseAddress"/>
          </baseAddressPrefixFilters>
        </serviceHostingEnvironment>
        <extensions>
          <behaviorExtensions>
            <add name="webAuthentication" type="WcfRestContrib.ServiceModel.Configuration.WebAuthentication.ConfigurationBehaviorElement, WcfRestContrib, Version=1.0.5.0, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
            <add name="errorHandler" type="WcfRestContrib.ServiceModel.Configuration.ErrorHandler.BehaviorElement, WcfRestContrib, Version=1.0.5.0, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
            <add name="webFormatter" type="WcfRestContrib.ServiceModel.Configuration.WebDispatchFormatter.ConfigurationBehaviorElement, WcfRestContrib, Version=1.0.5.0, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
            <add name="webErrorHandler" type="WcfRestContrib.ServiceModel.Configuration.WebErrorHandler.ConfigurationBehaviorElement, WcfRestContrib, Version=1.0.5.0, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/>
          </behaviorExtensions>
        </extensions>
        <bindings>
          <customBinding>
            <binding name="HttpStreamedRest">
              <httpTransport maxReceivedMessageSize="209715200" manualAddressing="true" />
            </binding>
            <binding name="HttpsStreamedRest">
              <httpsTransport maxReceivedMessageSize="209715200" manualAddressing="true" />
            </binding>
          </customBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="Rest">
     
              <webAuthentication
                requireSecureTransport="false"
                authenticationHandlerType="WcfRestContrib.ServiceModel.Dispatcher.WebBasicAuthenticationHandler, WcfRestContrib"
                usernamePasswordValidatorType="MyLibrary.Runtime.SecurityValidator, MyLibrary"
                source="MyRESTServiceRealm"/>
              <webFormatter>
                <formatters defaultMimeType="application/xml">
                  <formatter mimeTypes="application/xml,text/xml" type="WcfRestContrib.ServiceModel.Dispatcher.Formatters.PoxDataContract, WcfRestContrib"/>
                  <formatter mimeTypes="application/json" type="WcfRestContrib.ServiceModel.Dispatcher.Formatters.DataContractJson, WcfRestContrib"/>
                  <formatter mimeTypes="application/x-www-form-urlencoded" type="WcfRestContrib.ServiceModel.Dispatcher.Formatters.FormUrlEncoded, WcfRestContrib"/>
                </formatters>
              </webFormatter>
              <errorHandler errorHandlerType="WcfRestContrib.ServiceModel.Web.WebErrorHandler, WcfRestContrib"/>
              <webErrorHandler
                returnRawException="true"
                logHandlerType="MyLibrary.Runtime.LogHandler, MyLibrary"
                unhandledErrorMessage="An error has occured processing your request. Please contact technical support for further assistance."/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
      
    </configuration>
    
    So, whenever I upload this and change the ISS setting to Basic Authentication, it looks like it is trying to use the default handler for authentication as if I try to enter my web app user/pass, I get an error screen which has the following detailed information about the moduel/handler

    Detailed Error Information
    Module: IIS Web Core
    Notification:AuthenticateRequest
    Handler:svc-ISAPI-2.0
    Error Code:0x80070005

    Requested URL:http://www.mydomain.com:80/MyServiceBaseAddress/MyService.svc
    Physical Path:E:\web\xxxxxx\htdocs\MyServiceBaseAddress\MyService.svc
    Logon Method:Not yet determined
    Logon User:Not yet determined

    Now for the fun stuff... i tried my discountasp.net account username/password for kicks and sure enough it let me access any of the Operation Contracts which don't have [OperationAuthentication]. I thought this was strange, so I looked at fiddler and saw something interesting.

    Whenever I try to call one of the [OperationAuthentication] procedures using my discountasp.net username/pass I get two different "WWW-Authenticate" headers back in Fiddler:

    Code:
    WWW-Authenticate: Basic realm="MyRESTServiceRealm"
    
    WWW-Authenticate: Basic realm="www.mydomain.com"
    On the other hand, if I try to access the same procedures with only my application's user/pass, I only get the site's header:

    Code:
    WWW-Authenticate: Basic realm="www.mydomain.com"
    My conclusion is that for some reason I'm having to pass through the default "Basic Authorization" layer before I can get to the application's layer. I have no idea how this is possible or how to correct the issue, but I know that something is whacked. Any suggestions would be greatly appreciated! Thanks.
     
  2. Verified

    I created a new user for my service using my discountasp.net user/pass and verified the issue. I was able to successfully pass both layers of authentication this way... now how do I turn off the default one?
     
  3. Resolved

    I was able to enable only Anonymous Authentication in IIS which successfully allowed any request made to the service to bypass the default authentication process. :)
     
  4. mjp

    mjp

    Thanks for the follow up!
     

Share This Page