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

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.

Related

CSLA Permissions failing when deployed to server(s)

I have an ASP.NET MVC 4 application that is using CSLA.NET for a portion of our business logic. The permissions to read/write are handled through AD by a domain account, the same account as the Application Pool Identity and .NET Impersonation user. When testing on my local machine, the validation runs perfectly. Once the application is deployed to one of our test environments (dev or qa) I receive exceptions that seem to point to permissions. I've verified that the username being used by the assembly is indeed the correct user, but have been unable to set the values of any of the fields due to not having the appropriate permissions.
Anyone experienced anything like this before?
EDIT:
Link to discussion on lhotka.net forums
Web servers are stateless, so they don't generally remember anything between page or service requests. This includes the user's identity and roles.
If you are using ASP.NET forms security (or similar) the username will be automatically recreated on the server by using the .NET authn cookie token, but that's only the username.
You are responsible for recreating the complete principal/identity object on the server for each postback/request.
The easiest way to do this is in the global.asax file, often in the authenticate request event. There are samples in the CSLA download showing how to do this, and I discuss it in the 'Using CSLA 4' ebook series.
Also any good ASP.NET book will discuss restoring the principal, because this isn't really a CSLA issue as much as a web development issue.

Authenticate a call to a WCF service

I am trying to call a Sharepoint Web Service via WCF from inside a .ASHX on a different server. My code works if I run inside of Visual Studio's debug web server, but not from IIS. The working server works in various authentication modes (Kerberos, NTLM), and the non-working one doesn't work in any. I am impersonating the same user in both cases.
Using NTLM, I recorded a working session and non-working session in Wireshark. In the working one, Wireshark parses the NTLM data and reports a DOMAIN and USER NAME that I expect. In the non-working one, it shows
DOMAIN: NULL
USER NAME: NULL
I have debugged in IIS and impersonation is definitely working at the point of the service call. If I check WindowsIdentity.GetCurrent(), it's the user I expect.
If I inspect the WCF service proxy on the working and non-working servers, they look identical -- the part that deals with ClientCredentials is set to "" for Username and Password for both versions.
Any ideas on what else to check? Why would the NTLM data have DOMAIN and USER NAME set to NULL -- where does it pick that up from?
According to this:
http://support.microsoft.com/kb/207671
When IIS services an HTTP request, IIS performs impersonation so that access to resources to handle the request is limited appropriately. The impersonated security context is based on the kind of authentication performed for the request. The five different types of authentication available from IIS 4.0 are:
Authentication Type Impersonation Type
------------------------------------ ---------------------
Anonymous Access (no authentication) Network
Auto Password Synchronization is
ON (ON=default)
Anonymous Access (no authentication) IIS Clear Text
Auto Password Synchronization is OFF
Basic Authentication IIS Clear Text
NT Challenge/Response Authentication Network
Client SSL Certificate Mapping Interactive
In my case, I have a Network Token, but
Network tokens are "NOT" permitted to access network resources. (Network tokens are named so because this kind of token is traditionally created by a server when a user is authenticated across the network. To allow the server to use a network token to act as a network client and access another server is called "delegation" and is considered a possible security hole.)
The KB has many possible ways to avoid the problem

WCF Security - Newbie questions -

I've been reading about WCF security for a whole day and can't say I'm comfortable with it.
I've developed some WCF services and deployed them to a test server and can call from a client. Both sides C# / VS 2010. The services are hosted under IIS 6. No option to go more recent at the moment.
So - I've read that I can only use HTTP with IIS 6 - which I believe restricts me to basicHttpBinding or wsHttpBinding as the binding.
I've also read that the XML sent over the wire using wsHttpBinding is encrypted, whereas basicHttpBinding is not.
So it looks like I want to go with wsHttpBinding as I will want some sort of authentication and I suppose user name / password will be passed along with the incoming messages.
First question is - if I use wsHttpBinding do clients have to call using https? And then do I need to worry about certificates etc. on the server?
Second question is - what security options are available to me? Do the callers have to be Windows users on the server, or can I make up my own user name / password and have that part of the service and the service do the validation and have nothing to do with Windows users? If I have to go with Windows users I suppose it's common to set up one user account on the server and have all callers use that?
The basic idea is I need to open this service to selected callers, but don't want just anyone to be able to discover the service and call it. I need to control somehow who calls the service. Is user name / password the standard way of doing this? Could I define a GUID for example which all callers would have to pass?
In answer to your first question. wsHttpBinding does not require HTTPS. You can use HTTP if you set the SecurityMode to Message or None. However, since you are proposing to send a username and password with the service calls you definately shouldn't do that. If you do then anyone will be able to look at the message in transit and read the username and password and your security is totally compromised. I'm afraid you will have to get a certificate and use HTTPS. It's not so bad though and there are lots of resources on the web to help you.
By the way, you can do HTTPS with basicHttpBinding aswell as wsHttpBinding. Also, you should consider using REST for simplicity. WCF has good support for it (webHttpBinding) and better support coming with the Web API.
In answer to your second questions, you do not need the callers to be Windows users on your server and you can use a username and password. This is called Basic Authentication. Again, there is lots about it on the web. Start here.
If you do this you will obviously have to have a database to store usernames and password so you can validate then and grant or denay access to your service. The simplest way to achieve this with WCF is to use one of the default membership providers.

"Guarding" WCF service from certain users - application identity

We are using WCF services. Right now, we are using Windows Auth but this is not for long. Some services will sit outside the firewall and use username/password verified in the database.
My tech lead is "scared" at how easy any user can "Add Reference" to the services we have and just party on. He wants to "guard" the services by adding another identity - the application. He wants the service to accept requests from certain applications so the certain users cannot just use the service - add reference to it and call. It’s the notion of the application having an identity + credentials that is the operative principle here, as services on the network may need to authenticate those credentials prior to fulfilling a request, in order to prevent rogue code inside the network (i.e., NOT the application) from accessing services using “Joe User” end-user credentials.
Does this make any sense?
Then he believes the Juval Lowy's book has, in an Appendix that discusses sending more than one identity during a WCF call (Security Interceptor). There is no specific suggestion that all of those have to be end-user identities and if that is the case, one of those could be the identity of the application making the request.
How can this be done?
Thanks,
Sam
The problem with sending an application identity is that the secret used to confirm that identity has to be stored somewhere. If it is visible to one application on a machine then generally it will be visible to other applications running under the same identity.
Would your manager be happy with "it came from an authorised machine"? If that's the case you could simply use Client Certs
Its also worth taking a step back: if the user is authenticated and is authorized to perform the functionality they have requested, why do you care which application they came from - if they are who they say they are and they are allowed to do what they are requesting then why couldn't they use, say, fiddler to make the request - isn't that the point of a service (rather than a closely coupled client server app)?
You might want to look through Common Security Scenarios in the MSDN documentation to see if any of those options fit your needs.
The options that pops to my eye are Transport Security with Certificate Authentication and Message Security with Mutual Certificates. Both rely on X.509 certificates. The latter option is on the message level, so you can handle certificate delivery and security negotiation however you want.
To make it a lot harder for someone to add a reference to your service you could just remove the mex endpoint. This way it would be very difficult for a stranger to create a valid request message.
You can then distribute the WSDL manually, only to people you trust.

how to access MSMQ in web proxy class

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