how to access MSMQ in web proxy class - wcf

I've created a wcf web service hosted on IIS 5.1. In the service implementation class there is a method GetAlarm which access the MSMQ on that system. In a sample win form application i instantiate web proxy to call GetAlarm method. But the problem is that when i use GetAlarm method using proxy for local machine then it propmts error like "he queue does not exist or you do not have sufficient permissions to perform the operation.". While i've given all the users full permission in corresponding queue users (properties/security). I can access the rest of methods using web proxy but not msmq.
If i use the GetAlarm method without proxy then it works fine.
please help;
arvind

You say "I've given all the users full permission".
What permissions did you give and to which accounts?
An easy test for security issues is to temporarily give "Everyone" and "Anonymous Logon" Full Control to the queue. If that works then it is a permissions issue.
If you have given the permissions to the account that you think is accessing the queue but still get access denied then you could enable security auditing on the queue to check what account is actually being used.
Also see
https://stackoverflow.com/questions/4758627/how-to-access-message-queue-msmq-via-wcf
Cheers
John Breakwell

Related

IIS7 Post/Put/Patch/Delete WCF oData - Authentication Failure 401.3

After migrating from IIS6 to IIS7, all sites using a WCF oData service would prompt for credentials when attempting to make Post/Put/Patch/Delete request. The user would be continually prompted for credentials until the cancelled the request. After cancelling the request, they would receive a 401.3 response from the server.
If a user is granted modify permission on the folder containing the *.svc file for the WCF oData service they are then authorized to make requests with those verbs. Asp.Net impersonation is not turned on.
The AppPool is running Integrated .Net 4 under a service account with modify permissions to the site's folders/files.
Update:
It seems this is as designed. GrantingServerName\Users modify access to the *.svc, does resolve the issue. Addendum: Specifically, it looks like Domain Users or Authenticated Users needs modify rights to the *.svc.
Final update: changed the wording to make the question more general/easy to find for others
This is by design. If you disable impersonation, then NTFS ACLs are used to secure the resource. I know it seems odd at first, but some thought will lead you to an understanding that it is a reasonable approach given the constraints of this particular configuration. This behaviour is documented on MSDN.

WCF Windows Authentication / Delegation

I'm having trouble getting the user credentials to be delegated over to our Sql Server DB. I'm pretty sure I have my configuration for the WCF set up correctly because everything works on my local IIS where there is only one hop, the problem is getting the double hop to work in a real environment.
The first Error I was getting was a Sql Exception when trying to login with Network Service/anonymous Login. From reading blogs I think the service was falling back to NTLM which cannot perform the double hop.
First question, am I correct in thinking the only way to perform a double hop is with Kerberos?
I switched the config to not allow NTML and got a 'The requirement for mutual authentication was not met by the remote server' error.
I read that I needed to set up a user for delegation. This is where I get lost. The user of the AppPool is NetworkService, what do I need to do to get delegation to work for this? Do I go into the Domain Controller and enable Delegation somehow? What do I need to add to the client config to tell the service about delegation?
I did try adding a new domain user to active directory, enabling delegation for the user, and making the user for my app pool, and added an identity section in the config to speciy this user, but got this error: 'The target principal name is incorrect'.
If possible I would like to keep the network service as my app pool identity. Does anyone know what steps I need to take to get this work?

Pattern for WCF Kerberos Clients where Server uses User Account

We have a WCF (Windows Communication Foundation) client and service application. We're using Windows Authentication with Kerberos.
The issue is that the service may be run under one of many accounts (maybe Network Service, maybe a specific user account -- depends on the IT group). This account is not not likely to change daily, but possibly on occassion (every few months maybe). Additionally, we deliver this client/service package to several groups, and each group may have its own account that they use to run the service on (this is to just let you know that we can't do a custom solution for a single team).
Now the reason the above paragraph is an issue is apparently if the service is not running in the SYSTEM or NETWORK SERVICE account, i.e., a user account, then the client must specify the name of the user account in the identity of its endpoint.
For more on this restriction see: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/feb6bc31-9a4b-4f8d-a887-ef6d2c7abe41
and http://www.vistax64.com/indigo/146204-using-localhost-v-s-environment-machinename.html
Now this seemingly makes it tough to deal with the situation where the IT department changes the account that the service runs on. What is the pattern for handling this, if there is one? How have other people handled this? One solution I've thought of is that the admin sends out an email when the user account of the service has changed, which has a weblink to an application that updates the client or a config file, so the client refers to the new user account. But that seems hackish.
Admittedly, this is a lot like the URI of the endpoint moving. Except, I think there's a lot more expectation on behalf of people that changing the URI is something the client should have to know about, but changing the account the service is running on is something that should be relatively transparent to the client.
BTW, this is required to be hosted on IIS 7.0, if that matters.
I think you can set NegotiateServiceCredential property to True so your binding uses SPNego instead of hard-cold Kerberos. When is set to true, the client does not need to specify the SPN and it can connect to a server running a non-machine account.
Note that since the client no longer requests a specific SPN, it can no longer detect if is connected to a hijacked impersonator of the service, but this is usually a minor concern unless you are really paranoid about security.
Also, as a side rant: the fact that WCF requests as SPN the account name is basically a brain fart. It client should use the DsMakeSpn API to compose the SPN from the service name, host and port. The server should register that SPN for itslef at start up or let an administrator do it using setspn.exe. This is the way they do it by all traditional (well behaved) services in the Kerberos/ActiveDirecotry/Windows environment.
Update
On second though I don't see anything specifying that the client must use the account name as SPN. Looks more like a documentation oversight, instead of documenting the proper way they just recommended what is basically a bad practice. Or maybe just the forum advice is bad, since I did not dig to see what does the MSDN binding spec actually says about the SPN to use...
I don't have a WCF environment handy to test with, but perhaps you can configure the clients to requests a proper SPN like YourService/server:port and you also register the same SPN on the server side. Either manually as an exercise left to the admins, or automatically from your service when it starts up, and unregister it at shut down. The proper way to do it is to let the admins do it, but in reality that is such a pain that most services register the SPN themselves and you can probably follow this practice too. To register an SPN, your service calls DsWriteAccountSpn. The write has to propagate to the AD and be replicated between AD servers, and this at least one reason why having the service auto-register/auto-unregister the SPN is a questionable practice.
If you want to learn more about the wonderfool world of SPNs and how they can wreck your day, you can read up on How Service Publication and Service Principal Names Work.
Update
I'm pretty sure you can use any SPN you like. Most exmaples out there use the account name as 'UPN' (User Principal Name) instead of SPN, but that is just for the convenience of samples as using a true SPN would run into administrative issues setting up the SPN under an user account (again, why admins should do it...). From Overriding the Identity of a Service for Authentication, relevant emphasized:
By default, when a service is
configured to use a Windows
credential, an element that
contains a <userPrincipalName> or
<servicePrincipalName> element is
generated in the WSDL. If the service
is running under the LocalSystem,
LocalService, or NetworkService
account, a service principal name
(SPN) is generated by default in the
form of host/<hostname> because those
accounts have access to the computer's
SPN data. If the service is running
under a different account, Windows
Communication Foundation (WCF)
generates a UPN in the form of
<username>#<domainName>. This occurs
because Kerberos authentication
requires that a UPN or SPN be supplied
to the client to authenticate the
service.
You can also use the Setspn.exe tool
to register an additional SPN with a
service's account in a domain. You can
then use the SPN as the identity of
the service. To download the tool, see
Windows 2000 Resource Kit Tool :
Setspn.exe. For more information about
the tool, see Setspn Overview.
Set NegotiateServiceCredential and EstablishSecurityContext properties to False.

wcf operationContext

hello i have a desktop application that communicate with a wcf service that i building as well
i want to be able to manage the logged on users inside the server without a db (statefull server)
i also want the server to know how to handle 2 client from same computer, whats the simplest way of doing it?
i also have more than 1 service that the client work with (login service and app service)
is there any operationContext Property that can help me?
You can deffinetly manage the logged users inside the server. I have created a personal pattern for dealing with such situations, and it ussually goes like this:
create a client class inside the WCF server that will hold all the needed information about the client.
create 2 methods in the service: logIn, logOut. the login method should be able to gather all the informations about the client that you want to store. Make sure to define properties that can uniquely identify a client instance. When the client conencts to the server it calls the login method, allowing the server to gather and save the information from the client. If using callbacks, this is the place to save the CallBack context object, in the client obejt. You can now save the Client object in the WCF server instance (I use a dictioary). When the client logs out, it calls the log out method and the server removes the entry.
create a KeepAlive method in the server that regularry checks the connected clients to see if they are still connected (in case of network failure or app crash a client may not call the logout method).
I think this is the simplest way (not saying it's the best) to manage clients in the server.
There is no problem with having multiple clients from the same computer (you save the Context when a client logges in) as long as you have a way of uniquely identify clients.
As for your last question, having multiple services should not be a problem. In fact you have the same WCF server with different contracts (and endpoints) for the different services you offer. ALl the contracts reside in the same WCF server instance so they all can access the connected client list.
If you have further questions, I would be happy to answer them.

WCF service and ActiveDirectory

I am using a WCF call to update my database with any changes from ActiveDirectory.
I call this WCF functin via client browser and the function trys to get details from AD within the servive itself. However the issue is AD needs UserName and Password to get any records.
Please advise how can I overcome this problem so that Windows looged in credentials are automactically accepted and AD is read.
I am using wsHttPBinding,Security: message and clientCredentials="Windows".
Thanks
Vikram
The call to Active Directory is going from the service.
The default settings for the service is impersonate=false and the identity of the application pool is NETWORK SERVICE.
Therefore, the call to AD is going in the security context of Network Service, which does not have the correct access, and cannot be given them, since it is a machine local account.
There are 3 ways to fix this.
Set Authenticate=true in the web.config to allow access to AD to be done in the security context of the calling user.
Change the identity of the application pool to that of a domain user that is allowed to access AD. Be sure to add this user to the local IIS_WPG group.
Store the username and password of a user that is allowed to access AD, in the web.config file, and use these credentials to access AD.