Reputation: 5684
I have the following problem:
On my client, i call a asp.net
site which connects to my IIS
with a WCF
. I pass my Active Directory
user from the client and then from IIS
, i try to connect to the SQL-Server
(on the same machine as the IIS
).
Until here everything works fine! But when i try to get a connection to the database with the AD-user, I get an EntityCommandExecutionException
:
A transport-level error has occurred when sending the request to the server. (provider: Shared Memory Provider, error: 0
with the Inner Exception
Either a required impersonation level was not provided, or the provided impersonation level is invalid
I really don't know how to handle this or what to set up in IIS
or some web.config
to pass this user to database.
Maybe someone knows how to solve this specific problem?
EDIT:
Here is the Web.config for the WCF-Client:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<httpRuntime targetFramework="4.5" />
<compilation debug="true" targetFramework="4.5" />
<customErrors mode="Off"/>
<identity impersonate="true"/>
<authentication mode="Windows" />
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
<system.serviceModel>
<bindings>
<ws2007HttpBinding>
<binding name="ws2007Binding" closeTimeout="00:10:00" sendTimeout="00:10:00"
transactionFlow="false" >
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<client>
<endpoint address="http://server/service/Service.svc"
binding="ws2007HttpBinding" bindingConfiguration="" contract="Service.IService"
name="ws2007HttpBinding_IService">
<identity>
<servicePrincipalName value="MSSQLsvc/server:1433" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
and this one is for the WCF-Service:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<ws2007HttpBinding>
<binding name="ws2007Binding" closeTimeout="00:10:00" sendTimeout="00:10:00"
transactionFlow="false" >
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true"/>
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<protocolMapping>
<add binding="ws2007HttpBinding" scheme="http" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
</system.webServer>
<connectionStrings>
<add name="Entities" connectionString="metadata=res://*/Models.Model.csdl|res://*/Models.Model.ssdl|res://*/Models.Model.msl;provider=System.Data.SqlClient;provider connection string="data source=Server;initial catalog=Database;integrated security=False;User Id=user;password=password;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
Now i access the database once with the user in the Web.Config
where everything works fine, but when i try to delegate my AD-User and then connect to database i get an exception:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public List<string> GetInfo(string text)
{
using (var db = new Entities())
{
var someTempInfos = db.Infos.Find(text); //<-- EntityCommandExecutionException
...
}
}
Upvotes: 0
Views: 549
Reputation: 1325
We had a similar error and I was able to fix it by disabling the Shared Memory Provider, forcing the SQL client to use TCP/IP. In a production environment you'd almost never have SQL server on the same machine anyway so I suspect that's why this error doesn't occur much there.
Upvotes: 1
Reputation: 5684
Finally i got it working. i just forgot to set the Impersonation Level to Delegation
. So the solution is to set the Impersonation Level in the (client-)method after creating the service:
var service = ServiceFunctions.GetService();
if (service.ClientCredentials != null)
service.ClientCredentials.Windows.AllowedImpersonationLevel =
TokenImpersonationLevel.Delegation;
Upvotes: 1