I have wcf service using net.msmq protocol but service fails to activate with following error. What could be wrong?
Looks like it is trying to find machineid or something in AD but why?
Sevice name is like net.msmq://localhost/private/myservice.svc
A connection with Active Directory cannot be established. Verify that there are sufficient permissions to perform this operation.
System.Messaging.MessageQueue.GetMachineId(String machineName)
System.Messaging.MessageQueueCriteria.set_MachineName(String value)
System.Messaging.MessageQueue.GetPublicQueuesByMachine(String machineName)
System.ServiceModel.Channels.MsmqBindingMonitor.OnTimer(Object state)
What security settings to you have? By default, the MSMQ binding will expect users to present a certificate to authenticate them and needs access to AD to verify that certificate.
If you want to totally turn off all security, add this snippet to your config:
<bindings>
<netMsmqBinding>
<binding name="NoSecurity">
<security mode="off" />
</binding>
</netMsmqBinding>
</bindings>
<endpoint name="...." address="..." contract="....."
binding="netMsmqBinding" bindingConfiguration="NoSecurity" />
That way, you should be able to call MSMQ without access to AD.
Marc
Maybe it needs to check with AD to be able to write to the message queue.
If you are running under a local account that does not have access to AD you may get this error.
I've had this error when my WCF service is hosted by a Windows Service that is running as the LocalSystem or NetworkService account. Changing the Windows Service to run under an interactive login account, like my own account or one I create just to host MSMQ-WCF Windows Services, eliminates this problem.
I believe the error is not related to WCF, but rather the service not having an interactive login that can auto-retrieve an AD certificate that will allow the WCF code to communicate with MSMQ.
Related
We need to create a WCF service (.NET 4.0) that will be consumed by a client outside of our organization.
The case is that we have two servers that are behind a load balancer which terminates the SSL. This is where it gets confusing for me.
How we could and should handle the authentication?
The previous experience about WCF is only about services for internal use. If I understood correctly we should use basicHttpBinding to guarantee interoperability with Java based client. I don't know if this is an issue with JAX-WS based client.
There will only be this one client that is going to use the service.
We need to somehow ensure that caller is authenticated to use the
system
Make sure the message is encrypted when moving in public network
So far the best article that I found was
http://devproconnections.com/net-framework/wcf-and-ssl-processing-load-balancers
There were few suggestions how to do this.
WCF services can be configured for basic authentication and receive credentials in the clear over HTTP. This can work; however, it precludes passing credentials in the message, and the use of more interesting credentials (such as issued tokens).
We use forms authentication on our website under which the service will be hosted. I think it is not easy or even possible to make the service then use basic authentication.
WCF services can be configured to fake the presence of transport security so that the runtime will allow receiving message credentials without transport or message protection
Will this be the way to go and will this work with basicHttpBinding?
The client and server binding will be different. The client binding will use username auth in eitehr message or transport level with transport security (ssl):
<bindings>
<basicHttpBinding>
<binding name="NewBinding0">
<security mode="Message" />
</binding>
</basicHttpBinding>
</bindings>
then the server config will use the same config but without the transport security. If you chose to use message security then check out WCF ClearUsernameBinding. If you use trasnport security (basic http) then set mode="TransportCredentialOnly".
I've seen a lot of posts about the WCF double-hop issue with impersonation, but none of them have specifically helped me resolve my problem.
What am I missing? What else do I need to do in order to retain my Impersonated User (DOMAIN\UserName) over on Service 2? I'm looking at ServiceSecurityContext.Current.WindowsIdentity.Name to confirm - maybe that's wrong.
The Setup:
Client App hosted in localhost IIS with Service Reference to Service 1 - Impersonating WindowsIdentity (DOMAIN\UserName)
Service 1 - WCF Service hosted in localhost IIS with Service Reference to Service 2
Service 2 - WCF Service hosted in localhost IIS
I'm using ALL basicHttpBindings to keep things simple. I've set up SPNs on both service endpoints.
I can successfully MAKE the double-hop and the code executes just fine
In Service 1 (hop 1) my ServiceSecurityContext.Current.WindowsIdentity is the person that I impersonated (DOMAIN\UserName)
In Service 2 (hop 2), my ServiceSecurityContext.Current.WindowsIdentity is the IIS App Pool user
ImpersonationLevel = "Delegation"
Both WCF Services have Windows Authentication Enabled and Anonymous Disabled
** Note: I'm running this all locally on my dev box. Even so, I've had my delegation level set to allow delegation from myself to myself. Maybe overkill.
Binding (similar for both services):
<binding name="...">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
I've set the impersonationLevel = "Delegation" on both the WCF service client and the service endpoint behavior configuration. My service methods are specifically decorated with impersonationOption="Allowed" (hop 1) and impersonationOption"Required" (hop 2).
As it turns out, the critical piece in my case was ensuring the following behavior attribute was set:
<serviceAuthorization impersonateCallerForAllOperations="true" />
Previously, when I set this value, I was receiving errors in Entity Framework, so I undid the setting. It appears that somewhere along the line of aligning my setup to the standard implementation (as described in other varios posts) that I was able to eventually set this attribute and have it work as expected.
Edit:
If this all works locally, but doesn't work in a distributed environment, check out this post: How can I fix the Kerberos double-hop issue?. You probably need to set the machines to trust delegation between each other.
Even with all of the documentation available instructing me how to configure WCF to allow certificates over SSL, I'm having a hard time discerning where IIS' responsibilities lie and where the WCF's responsibilities lie.
For example, I do not have authority over my IIS server. I requested the admin to setup my virtual directory (application) to require certificates over ssl. I did this because when I tried to configure this security through my web.config, it told me that IIS wasn't setup to permit this.
After that, another developer told me that because the IIS Admin set it up this way, I only have to set security = none and client auth to none in my web.config because IIS will now handle this for my app.
Is this true? Also, is there documentation explaining the options of configuring IIS and WCF and some type of pipeline showing where these authentication processes occur?
Thank You.
Well, you definitely need to install a certificate and enable the SSL binding in IIS before anything will work. You must also set 'Security' mode to 'Transport', and 'clientCredentialType' to 'None'. This may be what your developer friend was getting at, though he is wrong to imply WCF doesn't need to do anything if security is setup in IIS.
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
You would then reference this binding in your service endpoint configuration. This page has a pretty clear step-by-step guide on what to do, though you will obviously need access to IIS to set this up.
The basic idea is that certificates are installed and managed by IIS, which also handles authentication. All WCF does is say what kind of security the service will be using/expecting. This page has a good discussion of Transport security over HTTP, as well as links to setting up IIS for this. Hope this helps!
I recently set up a wcf service for an outside company to access our data. The security practices are very hard to configure. I ended up bypassing the certificate and writing a custom auth class that authenticated a username and password in the header. Helpful references I found on my journey.
http://wcfsecurityguide.codeplex.com/releases/view/15892
http://msdn.microsoft.com/en-us/library/aa702565.aspx
I wish I could give you more my situation was not as vital for security so that had a major role in the route I took.
Trying to create an framework 4.0 WCF basicHttp service hosted by IIS (6) that is completely unauthenticated. Once deployed, I can successfully retrive the WSDL via a browser.
However whenever I try and connect to it via WCF Test Client or via a visual studio generated proxy, I'm getting "The server has rejected the client credentials.".
This still occurs when I add <security mode="None"/>, but my understanding is that this is the default anyway ...
In the IIS virtual directory properties I only have anonymous ticked, and in the web.config file <authentication mode="None"/> is set as well.
Any ideas?
Seems like the IIS site has anonymous authentication disabled. Check out this article on IIS 6 anonymous access configuration.
Turns out that the source of the exception was from an immediate attempt to connect to a downstream tcp service. As a workaround I ended up creating a plain jane webservice wrapper which successfully connects to the downstream service fine using a domain account specified in the <identity impersonate="true" userName=".." password=".." />.
Note, I've added a related question asking why one works and the other doesn't.
I have deployed wcf services in machineA and tried to accessed it through wcftestclient which is another system machineB. But i am getting error "The caller is not authenticated by wcf service". This wcf services is working fine when i testing it in machineA itself.
I have used wsHttpBinding.
How to solve this? Please help me.
on Machine A remove security if that service is only exposed in intranet.
Add binding configuration as follows
<binding name="none">
<security mode="None" />
</binding>
and In service add
bindingConfiguration="none"
If you don't want any security then only.
On machine B you'll have to supply some credentials that have access to the service on A.
See this article: Debugging Windows Authentication Errors for details, especially the section Client Credentials Are Not Set Correctly at the bottom of that document.