locked
WCF Dataservice with integrated Windows Authentication loses Credentials RRS feed

  • Allgemeine Diskussion

  • Hi folks,

    i've deployed a WCF Dataservice which uses integrated Windows authentication to pass the client user credentials to the database in the backend.

    This actually works fine, but after a certain peroid of time (approximately 20 minutes) the service somehow seems to lose the credentials of the client user and trys to connect to the database with anonymous logon. This fails and from then on the dataservice is unusable by this client.

    The client application has to be restarted to make it work again.

    On my development box this can't be reproduced, but i found the following difference between those environments:

    When i deployed my application to the staging/production environment i noticed that i had to send a http request to any entity by using HttpWebRequest directly prior to any call using the the dataservices client library to make integrated windows authentication work.
    If i skipped this call then i got the same error message as i get it now after ~20 minutes:
    The dataservices tries to connect with NT AUTHORITY\ANONYMOUS LOGON to the database and doesn't recognize the client credentials passed to the service.

    So this is probably the cause why it is working again after a restart of the client application. Because the HttpWebRequest is sent again.

    In my client application i set UsePostTunneling to true and set the Credentials-Property to CredentialCache.DefaultCredentials.

    I also catch the SendingRequest-Event and handle it like this to make sure no proxy server is used (for performance reasons) and that the credentials are definitely passed during every request:

      void proxy_SendingRequest(object sender, System.Data.Services.Client.SendingRequestEventArgs e)
    
      {
    
       e.Request.Proxy = null;
    
       this.Proxy.Credentials = CredentialCache.DefaultCredentials;
    
       e.Request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
    
      }

     

    Here is some information about my environment:

    Client:
    Windows XP SP 3 32bit
    .NET Framework 4.0

    Web Server:
    Windows Server 2003 32bit
    IIS 6

    Database Server:
    Windows Server 2003 64bit
    SQL Server 2005

    Client, Webserver and Database server are members of the same windows domain.

    My web.config looks like this:

    <?xml version="1.0"?>
    
    <!--
    
     For more information on how to configure your ASP.NET application, please 
    
    visit
    
     http://go.microsoft.com/fwlink/?LinkId=169433
    
     -->
    
    <configuration>
    
     <connectionStrings>
    
     <add name="lukasEntities" 
    
    connectionString="metadata=res://*/LukasModel.csdl|res://*/LukasModel.ssdl|res:/
    
    /*/LukasModel.msl;provider=System.Data.SqlClient;provider connection 
    
    string=&quot;Data Source=$(DB_SERVER);Initial Catalog=$(DB_NAME);Integrated 
    
    Security=True;MultipleActiveResultSets=True;Application 
    
    Name=EntityFramework&quot;" providerName="System.Data.EntityClient" />
    
     </connectionStrings>
    
     <system.web>
    
     <identity impersonate="true"/>
    
     </system.web>
    
     
    
     <system.webServer>
    
     <modules runAllManagedModulesForAllRequests="true" />
    
     </system.webServer>
    
     
    
     <system.serviceModel>
    
     <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    
     </system.serviceModel>
    
     
    
    </configuration>


    In IIS we have the following security settings:

    Directory:
    Read
    Execute permissions: Scripts only

    Integrated Security checked
    No anonymous access allowed

     

    I hope i didn't forget anything.

    So any help would be greatly appreciated to make the application work constantly because besides that WCF Dataservices are a really great technology!

    Thanks a lot for any help in advance!

    Greetings
    Markus

    PS: Unfortunately WCF Dataservices Forum wasn't availably to post this message to but i hope in the WCF Forum my question fits in as well!


    • Bearbeitet MarkusStrobl Mittwoch, 22. Juni 2011 07:47
    • Typ geändert Bogdan Petru Roiu Mittwoch, 6. Juli 2011 12:21 Frage wird auf en-US/adodotnetdataservices beantwortet
    Mittwoch, 22. Juni 2011 06:59

Alle Antworten

  • Here is the exception in detail i get when the services loses the client credentials:

     

    An error occurred while processing this request.
    
    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
     <code></code>
     <message xml:lang="de-AT">An error occurred while processing this request.</message>
     <innererror>
      <message>The underlying provider failed on Open.</message>
      <type>System.Data.EntityException</type>
      <stacktrace>  at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean&amp; closeStoreConnectionOnFailure)&#xD;
      at System.Data.EntityClient.EntityConnection.Open()&#xD;
      at System.Data.Objects.ObjectContext.EnsureConnection()&#xD;
      at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)&#xD;
      at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable&lt;T&gt;.GetEnumerator()&#xD;
      at System.Data.Objects.ObjectQuery`1.GetEnumeratorInternal()&#xD;
      at System.Data.Objects.ObjectQuery.System.Collections.IEnumerable.GetEnumerator()&#xD;
      at System.Data.Services.WebUtil.GetRequestEnumerator(IEnumerable enumerable)&#xD;
      at System.Data.Services.DataService`1.SerializeResponseBody(RequestDescription description, IDataService dataService)&#xD;
      at System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description)&#xD;
      at System.Data.Services.DataService`1.HandleRequest()</stacktrace>
      <internalexception>
       <message>Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.</message>
       <type>System.Data.SqlClient.SqlException</type>
       <stacktrace>  at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)&#xD;
      at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()&#xD;
      at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)&#xD;
      at System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)&#xD;
      at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, SqlConnection owningObject)&#xD;
      at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)&#xD;
      at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, TimeoutTimer timeout, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)&#xD;
      at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)&#xD;
      at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)&#xD;
      at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)&#xD;
      at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)&#xD;
      at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)&#xD;
      at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)&#xD;
      at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)&#xD;
      at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)&#xD;
      at System.Data.SqlClient.SqlConnection.Open()&#xD;
      at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean&amp; closeStoreConnectionOnFailure)</stacktrace>
      </internalexception>
     </innererror>
    </error>

     

    Mittwoch, 22. Juni 2011 07:32
  • Well i was now able to put my problem to the right forum. Sorry for cross-posting!
    Mittwoch, 22. Juni 2011 07:46