简体   繁体   中英

Impersionation like in ASP.NET for WCF Service

I've got a WebService with ASP.NET sites and WCF services in the same web.config. Until now, I was able to use the ASP.NET impersionation in the WCF services by setting

<system.web>
    <compilation targetFramework="4.0" debug="false"/>
    <!-- switch custom errors of-->
    <identity impersonate="true"/>
    <customErrors mode="Off"/>
</system.web>

However, now (for other reasons-> Cookieless Session state for the ASP.NET part) I have to set the

aspNetCompatibilityEnabled="true" 

option to false. With this I loose the ASP.NET impersionation for the WCF services. One of my WCF services needs impersionation for IO operations on the server... I would like to know how to get the same impersionation I had before by directly defining it on the WCF service configuration.

What I have tried (unsucessfully) is to set

[OperationBehavior(Impersonation = ImpersonationOption.Required)]

on the implementation of the methods in the WCF service and then specifying

<endpoint address="" binding="wsHttpBinding" contract="IService">
  <identity>
    <servicePrincipalName value="HOST/YourMachineName" />
    <dns value="" />
  </identity>
</endpoint>

in the web.config (obviously with the correct values for my service), as described in http://msdn.microsoft.com/en-us/library/ff650591.aspx .

However, the WCF service can not be called anymore after this... It tells me that the WsHttpBinding does not offer an identity for the contract.

Am I missing something important?

Edit: Translation of the error message:

: The contract operation '{0}' requires Windows identity for automatic impersonation. A Windows identity that represents the caller is not provided by binding ('{1}','{2}') for contract ('{3}','{4}'.

(The original error message was german...)

Try adding someting similar to this

<system.serviceModel>
        <behaviors>
            <endpointBehaviors>
                <behavior name="DelegationBehaviour">
                    <clientCredentials>
                        <windows allowNtlm="false" allowedImpersonationLevel="Delegation"></windows>
                    </clientCredentials>
                    <dataContractSerializer maxItemsInObjectGraph="4194304"></dataContractSerializer>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_SampleWebService" >
                    <readerQuotas maxArrayLength="16384" maxBytesPerRead="4096" maxDepth="32" maxNameTableCharCount="16384" maxStringContentLength="8192"></readerQuotas>
                    <security mode="TransportCredentialOnly">
                        <message algorithmSuite="Default" clientCredentialType="UserName"></message>
                        <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""></transport>
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://server/WebServices/Service/Service.svc" behaviorConfiguration="DelegationBehaviour" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_SampleWebService" contract="SampleWS" name="BasicHttpBinding_SampleEndpoint"></endpoint>
        </client>
    </system.serviceModel>

This is the server side code

 <system.serviceModel>
    <services>
      <service behaviorConfiguration="CustomBehavior" name="CustomWebService">
        <endpoint address="" behaviorConfiguration="" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding_Service" contract="WebService"/>
      </service>
    </services>
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpBinding_Service" maxReceivedMessageSize="4194304" receiveTimeout="00:30:00">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows"/>
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CustomBehavior">
          <dataContractSerializer maxItemsInObjectGraph="4194304" ignoreExtensionDataObject="True"/>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
          <serviceAuthorization impersonateCallerForAllOperations="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

As well as having these over our WebMethods

<WebMethod(), OperationContract(), OperationBehavior(Impersonation:=ImpersonationOption.Required)> _

Works for us

Well, in the end I just made the binding use Windows authentication:

 <security mode="TransportWithMessageCredential">
        <message  negotiateServiceCredential="false" clientCredentialType="Windows" algorithmSuite="Default"/>
        <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
 </security>

and passed a specific Windows user/pwd combination in the client:

channelFactory.Credentials.Windows.ClientCredential = new NetworkCredential(@"", "", "");
channelFactory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

Additionally I had to specifically use the newly impersonated user in the code of the web service:

 using (var imp = ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
 {
     // do IO here
 }

Well, the actual (underlying) question still remains:

How is it possible to emulate the ASP.NET functionality correctly...

For the moment I'm ok with the solution, however I've got the feeling that I've missed an important point about the ASP.NET impersonation.

Thanks a lot to Iain, although it wasn't exactly the correct answer, it at least got me on the right track!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM