开发者

WCF Service as consumer of another WCF Service

In a Project being upgraded I have to Consume a WCF service ( Service A) published by 3rd party ( no Control) in my WCF Service. I have been using ServiceA in My Web App project ( vs2008) and it has been working fine.

I started by Adding Service Reference in my WCF Project ( ServiceB). Lets say Name of the Service is "XYZ". VS created all required files but when I tried to compile it gave error

The type name 'XYZ' does not exist in the type 'ServiceB.ServiceB';

My 'Service B' has 'ServiceB.SVC'

I tried to overcome this by removing namespace "ServiceB." from Reference.cs file and Its content. This code could then be compiled.

Now I get Exception that

"The caller was not authenticated by the service."

Inner exception

The request for security token could not be satisfied because authentication failed.

at System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target) at System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)

=>

((System.ServiceModel.FaultException)(ex.InnerException)).Message The request for security token could not be satisfied because authentication failed.

The Web.Config File on ServiceB is as follows:

 <wsHttpBinding>
        <binding name="WSHttpBinding_IABCService" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
          maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
          textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
            enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true"
              algorithmSuite="Default" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://aaaaa/ ServiceA.svc"
        binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IABCService"
        contract="XYZ.IABCService" name="WSHttpBinding_IABCService">
        <identity>
          <servicePrincipalName value="host/[hostname]" />
        </identity>
      &l开发者_运维知识库t;/endpoint>
    </client>

======

I made my self believe that may be the problem is in WCF accessing WCF. I created a Web Service (.asmx) and added reference to ServiceA . When I debug by invoking the method I get the results from ServiceA . Hoping this was a solution that I can use till I figure out between WCF and WCF issue, I added reference to asmx service to My WCF Service ( ServiceB). When I debug by Running ServiceB --> asmx --> Service A, I again get Authentication failed for user error!!!

I believe it has something to do with Identity being impersonated ...

I read that ServiceB's web.config taking Priority over asmx web.config but I was not able to get to a solution.

I cannot turn off " Security Mode=None" as then Service A responds by saying no tokens were passed.

Any help will be appreciated: Remember that I am able to use the WC Service A from WebApp and from asmx but not from another WCF directly or Indirectly.

Thank you

Mar


This has nothing at all to do with WCF calling WCF. Try to imagine that WCF calling WCF causes compile errors - and that you're the first person in the world to discover this since 2006!

Try to fully qualify the "XYZ" type, spelling out the full namespace. If that doesn't work, then right-click each service reference and choose "View in Object Browser". Look to see what the full name of the types is.

If none of this helps you, then please post complete error messages and/or exceptions.

And, please don't ever edit Reference.cs. Any of your edits would be destroyed the next time that "Update Service Reference" is performed. Therefore, any change you think you want to make to Reference.cs can either be done in a better way without changing it, or else you really don't want to make that change at all (like the change you made).


It seem to me that you need to have a delegation instead of impersonation. To convert current users token to another one you can use DuplicateToken DuplicateTokenEx (the last one can produce TokenPrimary) with SecurityDelegation SecurityImpersonation (SECURITY_IMPERSONATION_LEVEL) and then WindowsIdentity(IntPtr) constructor. See LogonUser and delegation as a example.

Another way is Protocol Transition: S4U, S4U2Self (see http://msdn.microsoft.com/en-us/magazine/cc163500.aspx, http://msdn.microsoft.com/en-us/library/ff650469.aspx, http://msdn.microsoft.com/en-us/library/ms998355.aspx). You can use something like new WindowsIdentity(clientUPN).Impersonate().


If you have to do a delegation (i.e. act as original caller) process is described in detail on this MSDN Forum thread. Don't use a full trust delegation -- it requires admin permissions for AD and it is not a good thing from security prospective. Constrained delegation is easy to setup correctly if you know which names to use in SETSPN command. Also make sure you run service B (the delegator) using domain user account, machine accounts like Network Service/Local Service or local user accounts won't work because you won't be able to create SPN for those.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜