Authenticating call to WCF / Web Service from ASP.Net MVC - wcf

Basic question here (I think), I was hoping someone could point me in the right direction. I don't know much about WCF but I'd like to create a web service to be called from an ASP.Net MVC application. The goal is to make sure only authorized ASP.Net users (we're using forms authentication) can call the web service, not just anyone. Are there tutorials out there I can look at on how to approach this? Many thanks.

I assume from the question that you don't care what the end (MVC) user ID is that is hitting the WCF service (in other words you don't need a specific authenticated user to hit the WCF so you can get the ID of that specific user (i.e. so you know that joeBobUser hit the WCF)). you just want to make sure that user is authenticated and authorized to use the site. You don't need every potential user of your MVC app to be authenticated/authorized.
As long as that is true, then my approach would be as follows:
run your MVC app as a specific, known user account (i.e. set up the app pool in IIS to runas a domain user such as yourdomain\youMvcAccount) instead of the default asp account. There are lots sites that have instructions on how to make this happen if you are not already running your mvc app as a domain user.
set up your WCF service endpoint configuration binding as WsHttp. Again, many sites describe how to do this. here's one that does it via GUI (I prefer hand-editing the config but whatever). So now your WCF service will only accept secure, authenticated requests
create your WCF client proxy in the MVC app. easiest way to do this (probably not best re: separation of concerns, but just to get started) is just add new web service and discover you WCF endpoint that way. Again, basic stuff easily googable if you don't know how to do that.
Now your MVC app will be making the call to the WCF service authenticated. However, at this point, any client authenticated in your domain can call the service. You are now accepting ONLY authenticated but ANY authorized user. All calls issued from your MVC app hitting the WCF will be from the identity yourDomain\yourMvcApp
Restrict authorization to the identity set in #1 restricting (authorizing) authenticated users can be done a number of ways. The get'r'done fast way (but not very flexible as any change requires recompile) is just to check the identity of the request is the same as the identity of your WCF service directly in your service call. Alternatively, you can set up more robust (with the concurrently more goo) options such as AzMan or other WCF authentication rule sets. Again, many sites have instructions on setting that sort of thing up after you have an authenticated user. Here is a SO question that limits authorization to a windows group post (I'd do it that way--more flexible but you need to add that user to a group on your domain), and another article that goes more into the details of WCF security and allowing only a specific user access to the service.

Related

ASP.NET Client Application Services Authentication and WCF

I have a WPF application that uses Client Application Services to allow authentication (username/password logon) against a related web application that uses Forms authentication and the SqlMembershipProvider/SqlProfileProvider/SqlRoleProvider. This all works and I can reliably validate a user/password combination.
The WPF application also calls a number of WCF services that are exposed by the same web application as is used for the CAS authentication. I now want to be able to pass through the authentication details (from Client Application Services) to the WCF services in order that I can identify the user that was authenticated within those services. I also need to be able to prevent the WCF services from being used if no authentication has taken place.
I have found a couple of .NET 3.5 examples where CAS authentication is used against .asmx web services, or authentication is provided against WCF Data Services which does not use ClientBase and has authentication facilities built in, but I cannot find any examples with pure WCF. Can anybody point me toward instruction that will enable this scenario? I am using .NET 4.0 for this project.
I have also found this stackoverflow question but again this is answered for .asmx web services and not for WCF.
The closest I have gotten involves the creation of an OperationContextScope and then copying the cookie header from the ClientFormsIdentity object to an HttpRequestMessageProperty and adding this to the OutgoingMessageProperties of the current OperationContext. I then call one or more methods of the service within the lifespan of the OperationContextScope. Thing is, when I then get to the WCF service, I still cannot see anything that resembles authentication in such a way as I can identify the original user. This methodology has been taken from various examples but I am obviously missing a step at the WCF end.
I think you need to switch to the Web API that Microsoft is now having people use for WCF Services. Check out Using Forms Authentication with Web API and http://aamirposwal.blogspot.com/2012/05/aspnet-web-api-custom-authorize-and.html
Found it.
In my binding, I specified allowCookies="true".
According to Wiktor Zychla, "setting the AllowCookies property on a BasicHttpBinding to true turns on the automatic cookie management" - this means that any attempt to set a cookie in code will be ignored and this is what I was doing.

Securing WCF Services across multiple projects

I'm having a hard time wrapping my head around some architectural elements to securing a core WCF service that is consumed by many different applications.
Internally, we have an application that allows HR folks to update a peron's details. This is contained in a WPF app. Externally, we have a website that would allow individual people to authenticate (throuh an AD Membership provider) and update their details.
We don't want users to be able to see other user's information (for obvious reasons). But we don't want to host this service inside the same web application that the users would log into. Here is how the architecture would look from a visual studio perspective:
ServiceApplication
WpfApplication
MVCWebApplication
They don't exist inside the same domains, for example, the service application would be hosted at http://www.service1.com/Service.svc and the mvc application would be hosted at http://www.updateyourprofile.com . So a user logs into http://www.updateyourprofile.com and we'd like to hit a Wcf service via JSON. Both the service application, wpf application, and mvc web application would use AD credentials to authenticate. But how do we secure the service so that users who log into the mvc web application can only see their information?
Most of the examples I see say to use the HttpContext.Current.User check inside the service. But since the user authenticated at a different site, how does the cookie transfer? Do you end up having to publish your service inside the same web application that you want to consume so that the cookies travel transparently?
Or is it just not possible to have a centrally located service with disparate applications that use the same authentication store to determine who has access to what on the service?
What you are looking for is some kind of federated authentication system which is used by all the entry points. That is what Windows Identity Foundation can help you to build.
Inside each application, access control would be claims-based, according to the claims embedded in each user's security token issued by the authentication system.
There's an entire book on the subject on MSDN.

Need to authenticate users through a WCF service that is connected to a database

I'm getting increasingly frustrated with doing the authentication right. Usually I'm using terms that I'm not familiar with so answerers misunderstand my questions. Its not helped bu the fact that this is a case with many implementations.
So now I'm going to try to explain the facts and requirements surrounding my project so that I might get a pointer towards a good solution.
I will have a Database that includes the information I need. Included in this info will be the usernames and salted hash of passwords. This database will be connected to a WCF web service that supplies the data to other front end projects.
One of the front end projects is a asp.net MVC 3 web site that users will use to log in and such. Now the default in such a project is some sort of SQlMembership that is not right in this case as this site is not connected to the database (it might not even be a MSQL database).
Here are implementations that I looked at but couldn't quite figure how to use correctly.
1) Write my own MembershipProvider in the MVC project that would query the WebService for validation. Here I mean that it would just call some methods for all its needs. Not liking it for security issues, client side solution.
2) Validata using a service side MembershipProvider but then I would have to send userName Password with each action and I can't store password for security reasons.
3) Then I discovered something called WCF authenticationService http://msdn.microsoft.com/en-us/library/system.web.applicationservices.authenticationservice.aspx and it seemed to be what I need but I'm having problem understanding how it works. I wan't it to be part of my service but it seems to be a dedicated service. Also its not really explaining how it authenticates (I need to have a custom authentication based on my table, not some default table created for me). Here is a post Should authentication be in a separate service for wcf? with same problem that I'm not sure how got solved.
Can the WCF authentication service be the right tool for me?
Can you answer this for someone who doesn't know asp.net, web or service terminology?
EDIT
Here is one solution that I was hoping for but not sure if exists.
The WCF Service exposes a MembershipProvider, RoleProvider, ProfileProvider that are defined in the service.
In the MVC web.config under membership\providers\add the MembershipProvider is added along with a endpoint towards the service. Same with RoleManager etc.
So when I call MembershipProvider in the MVC project to validate user it automatically calls the service and checks there and when it happens upon a Authorize attribute it as well checks the RoleProvider in the service automatically.
I would however also want to restrict the service calls themselves, even if they are inside a [Authorized] attribute method it might not be so in other clients that reference the web service. Would love if when a call comes from a website the service would automatically have access to the forms.authentication cookie.
I am not clear as to what you want to authenticate exactly, if the user login in, or the user accessing you service. Also, I am not sure how you mean for an answer about WCF Security not to use service terminology nor how you expect to solve this without knowing asp.net. I'll do my best though.
If you are authenticating a user login in, you can implement your own MembershipProvider and have a service request credentials and return the authenticated user.
Once authenticated, you can assign each user a GUID. This GUID is the ID which will travel with each message (encoded in the message header) and validate the user to call the service method.
This doesn't involve transport security, which you should configure if you want your message to be secure over the wire, yet this is a different matter, not involving authentication.
Hope this can somehow help you. I tried to make it the least technical possible and left out anything too complicated. Hope this helps somehow...

iPad to WCF Services authentication

I am currently working on a project that has an iPad application that uses JSON to call WCF services hosted with IIS. One of the requirements is that the WCF services needs to use IIS Basic Authentication to login. Once the user has been authenticated from the database, a few values need to set to a cookie for return trips to other WCF functions (similar to asp.net session variables). Is this possible with WCF and using cookies to hold state? If not, any recommended method?
Thank you.
WCF absolutely supports basic authentication. http://msdn.microsoft.com/en-us/library/ms733775.aspx has details on this. WCF will then identify this user on all messages that come through.
If you want to implement a customer authorization mechanic, you will need to implement ServiceAuthorizationManager. I've recently done something similar where I have iOS clients that use OAuth to authenticate with our services. I have this implemented a ServiceAuthorizationManager to determine who they are and what privileges that they have. Might be worth looking into.

SOAP Header with identity of final client

The environment is in-house service based applications running in a Windows environment with WCF.
There are several "middle-tier" ASP.NET Web Applications and Web Services that authenticate the final client using Windows authentication, and use ASP.NET Roles to set Thread.CurrentPrincipal to a suitable RolePrincipal. These applications each run under their own service account, which is a domain account, and are considered to be trusted subsystems.
Some back-end WCF web services that may only be accessed by these trusted "middle-tier" applications. They use Windows Authentication to limit access to the service accounts used by these applications.
We now have a requirement for the back-end services to audit the identity of the final client whose call to the middle-tier application resulted in the call to the back-end service.
To avoid making any application changes, I was thinking of writing an endpoint behavior which inserts a SOAP Header with the final client's identity into the request sent to the back-end service. Note that the middle-tier applications are trusted, so no authentication of this SOAP Header would be required.
It occurred to me that this requirement may not be unique, so before I invent my own SOAP Header for this purpose I thought I'd ask if there exist any standards in this area I could reuse?
It sounds like you're after WCF Impersonation, check out the MSDN Link or Google that search term for more info. I've never used it myself so can't fully advise, but hopefully it's what you're after. Good luck
Edit: Does the WCF OperationContext not carry through the identity to the second phase? (OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name)