We are building an application that has multiple WCF services hosted in IIS on multiple machines within a customer's topography. The services need the ability to access network resources (hops to other WCF services, database, file system, and active directory).
We have been treating public services as trusted subsytems: access to the public service is authenticated and authorized using the user's identity, but access to other resources within the service are executed under a trusted identity.
Here is my question. What is the best way to access the other resources under the trusted identity
- Run the App Pool as Network Service and Impersonate when access to the resource is required. Seems kind of messy having to store the trusted identity's credentials in the web.config. Also having some issues with SqlConnection in this model (see below)
- Run the App Pool as Network Service and grant MachineName\Network Service$ access to all resources. This is a pain, especially when you have many machines that need access to a database and Active Directory.
- Run the App Pool as the Trusted Identity. Could cause issues with security at some customer sites
We are currently using option 1, but in addition to the issues I have with storing credentials in the web.config file (encrypted or otherwise), I'm also having an intermitent issue arise within our ConnectionFactory class. I wanted to keep developers from having to impersonate every time they access the database, so our ConnectionFactory impersonates using LoginUserA, opens the connection, undoes impersonation, and returns the open connection. This will occasionaly throw an ObjectDisposedException: Safe handle has been closed.
Any thoughts or suggestions would be much appreciated.
-Eric

Trusted Subsystem Implementation
DevboyX
Thank you for the reply.
I started to go down the route #3, until I realized the reason I went with #1 to begin with. I would like to have the following bindings exposed by my service to enable a trusted subsystem:
<basicHttpBinding>
<binding name="ExternalBinding">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
<binding name="InternalBinding" messageEncoding="Mtom">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
ExternalBinding is for the smart client application, InternalBinding is for service-to-service communication. When the identity of IIS is running under the trusted identity (domain\serviceName) windows authentication only works when the services are hosted on the same physical machine.
For example, this is what I would like to achieve:
The above works fine when ServiceA and ServiceB are on the same machine, but the second hop fails when they are on seperate machines. I assume this is an spn issue, but am not positive.
Any ideas
Dave2UisDave2Me
Thank you for the response Hao. This is a possiblity, but it could end up being messy on our clients who will be scaling out (we will have ~100 services located in 8 different assemblies)
Would it be a security issue to open up anonymous authentication on the virtual directory Doing this allows you to navigate to the site from IE and add a web refrence from VS.NET 2003.
Therefore, any user would be able to access the wsdl, but WCF will still enforce NTLM authentication to invoke service ops.
Jon Limjap
I did not try that, wil this work even when the IIS AppPool is running under a domain account
This has to be a common problem. In ASP.NET web services we had the ability to
<identity impersoante="true" username="domain\user" password="password">.
Now it seems I have to run IIS under the trusted identity to get this functionality, therefore I have this configuration:
The above configuration disallows someone to navigate to the service from a browser and "Add Web Reference" dialog from another machine. You receive a challenge/response, but credentials do not work b/c the domain account is not an associated spn on the machine.
pkazaria
I have tried ServiceA and ServiceB on both Server 2003 and Vista. Our domain controller is running Server 2003.
The error I am getting when ServiceA attempts to hop to ServiceB (only on different machines) is:
The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header receivedfrom the server was 'Negotiate oX4wfKADCgEBonUEc2BxBgkqhkiG9xIBAgIDAH5iMGCgAwIBBaEDAgEepBEYDzIwMDcwMjEwMDE1MTMxWqUFAgMPDESmAwIBKakMGwpTT='.
It seems to allow the multi-hop when I use <transport clientCredentialType="Ntlm" /> on the InternalBinding.
I still dont understand why I get the above error with <transport clientCredentialType="Windows" /> . If the ServiceA is running under the trusted domain identity, ServiceB should be able to authenticate it. I am not attempting to delegate the credentials from the Client to ServiceA then to ServiceB.
Iggy2
PARVAIZ
IE does not allow me to navigate to the service when:
Basicly, I get a challenge response, but am unable to authenticate.
rahulmanasa
Unless there is a way to force IE to do NTLM authentication, I don't know if there is a way to work around this issue, so it may not be a good idea to run AppPool under a domain identity.
If your services are only deployed on a controllable set of machines, your second option may not be a bad solution. You can enable Windows integrated security and control the access based on the machine accounts.
R3dD0g
Hao, thanks for the reply!
-Eric
Geogy
Can you describe the failure a bit more, perhaps the stack trace of the error on the service
Does the account that the service is running under have network credentials
bobo224
CommonMan53
1. You set this on the client side. For example
Bradrover
Option 3 strikes me as the best approach, provided the implementation leaves the deploying site the flexibility to choose the trusted identity. What other security issues are you concerned about
Doing a significant amount under impersonation can be gotten to work, but it's often an involved process. Generally, development costs are lower if a non-impersonating approach can be used. Impersonation's primarily meant for simplifying access checks.
Feng26
egor598
Here is some more information.
I am running the application pool under a trusted account (domain\ServiceAccount). Within IIS, the selected authentication modes are Basic (for smart client access) and Windows (for service<->service communication). I can't even navigate to the service from another machine using IE (http://machinename/service/service.svc). I get a challenge dialog, enter valid credentials and receive a 401.1 - Unauthorized: Access is denied due to invalid credentials.
As stated above, I think this is an spn issue. Here is the KB that details the issue http://support.microsoft.com/kb/871179/ and an excerpt:
This behavior may occur if the following conditions are true:
In this scenario, when Integrated Windows authentication tries to use Kerberos, Kerberos authentication may not work. To use Kerberos authentication, a service must register its service principal name (SPN) under the account in the Active Directory directory service that the service is running under. By default, Active Directory registers the network basic input/output system (NetBIOS) computer name. Active Directory also permits the Network Service or the Local System account to use Kerberos.
Is there a better solution I dont want our clients to have to run setspn on all of the machines that are hosting services (it's a large app, could have 10+ servers), as setspn requires domain admin rights.