Our application architecture is as follows:
1) WCF service acts as a facade layer and sits on top of Service, Business Logic and Data Access layer
2) Every client, be it an MVC/ASP.NET, or any other type of application has a ClientTag that first needs to be authenticated and issued an "access token". This token is then passed by the client with every message into the Facade layer
3) The system will be hosted on Windows Azure
This would have been easy to implement with WCF sessions like so:
1) Client initiates a call to WCF to get the token (Client to WCF Session is established, thus every subsequent communication is part of the same "conversation")
2) WCF authenticates the ClientTag, issues the token, and stores it as a local variable
3) Client stores the token in it's own Session and pass it to WCF with every request
Where it breaks down is the fact that Azure (due to its high-availability/load-balancing nature) doesn't support WCF sessions. So, the questions is how do we implement this.
One solution is to use AppFabric caching to imitate session state in WCF layer. We would store the Access Token there and then validate it against what the client passes in. The problem with this is that there is no concurrency between client and WCF. So, we would have to advance WCF session timeout on every request from the same client but we'd want to avoid updating the cache on every request (it could be hundreds/sec).
Any suggestions? Has anyone implemented anything similar to this on Azure. Any feedback would be greatly appreciated.
P.S. It's not only authentication that would happen on the server, but also custom authorization for each client. (Some client might have access to some functions, and others might not).
Thanks!
I'm in the middle of implementing something directly similar to this, but using OAuth 2.0 as the authentication architecture through ACS.
The model I'm following is shamelessly stolen copied from an MSDN sample here: https://connect.microsoft.com/site1168/Downloads/DownloadDetails.aspx?DownloadID=35417. This assumes the client has a user interface, so the user can present some kind of username and password either directly or through some third-party identity provider.
The advantage of this approach is that the WCF layer doesn't need to use any kind of session state, so there's no tedious mucking about with machine keys or whatnot. You'll still get something that can be mapped to an IPrincipal, however, so if you want you can create a custom RoleProvider and use declarative roles in the usual way.
Note the sample uses old-school ASP.NET, and has a dependency on an opaque (and possibly rather buggy) assembly Microsoft.IdentityModel.Protocols.Oauth. And, unless I'm missing something, I've not seen this released anywhere else (e.g. as part of Windows Identity Foundation) so I suspect it's rather new.
An alternative approach could again be to use ACS, this time to authenticate a SAML token, again following the OAuth 2.0 protocols. Details and sample code is here: http://msdn.microsoft.com/en-us/library/windowsazure/hh127795.aspx. That may be better suited to a system with no UI.
Related
I have read about various implementations of authentication and authorization for WCF, starting from reusing some built in .NET and WCF features and ending with completely custom implementations.
But there are so many factors to take into account, so I'm confused about how to implement it for my intranet business application project.
Here is what I need:
- WCF .NET 4.5 services will be hosted in IIS 7 or newer.
Most probably, ASP.NET compatibility will be disabled.
Protocol will be HTTP with BasicHttpBinding, but it might need binary serialization to minimize traffic.
WCF method will receive a custom session ID which will be checked against a user session object in a database. No .NET sessions are allowed in this project.
After receiving the ID, the service will read the corresponding user data (including authorization flags to see if the user is allowed to execute the current operation) and validate it. If data is invalid, an exception will be thrown and the WCF operation won't be executed. If validation succeeds, the identity of the user will be stored in a current operation context (and also current thread principal) so it can be accessed by various components during the WCF operation execution.
All the authentication&authorization should be done transparently before the execution of the WCF operation - without additional efforts from programmers who will create the WCF methods.
I need access to the WCF operation name being executed, when I perform the auth validations, so I can throw an exception if the user does not have permissions to execute the operation.
testers will use SoapUI, so they'll need to be able to pass the session ID through standard SOAP or HTTP headers.
Which would be the most straightforward way to implement my auth routines? Should I use a custom binding? Custom behavior? Some kind of a built-in request event handler (which one exactly, and will they work if ASP.NET compatibility is disabled)? Authorization policy (seems a bit overkill because I won't be using most of its built-in features anyway)? Something else?
You can try making use of Message Inspectors. Your session ID can be passed like a token through SOAP or HTTP Headers and will be inspected by WCF through your defined behavior before it executes the actual service operation.
You can check the articles here and here, particularly focusing on the IDispatchMessageInspector interface which offers the "AfterReceiveRequest" and "BeforeReceiveReply" methods.
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...
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.
I'm having a hard time getting my head around this, and Google just isn't being helpful.
I'm looking at converting some legacy code to use the following technologies: ASP.NET, WCF, jQuery.
The ASP.NET conversion isn't an issue, nor is accessing the WCF service for data, on the server-side.
However, what I'm having an issue with is potentially being able to secure the service so that I can return JSON-formatted data, requested via jQuery on the client-side, but lock it down to prevent external access.
For this particular implementation, it's not that big of a deal, since the ... quasi-Ajax-like functionality has been in place for quite a while, and there hasn't been abuse.
But, once this project is complete, I'd like to take what I've learned and convert another form, which is often abused, and allow for a slicker display.
If I want to do client-side calls to a Web service, am I stuck making my Web service open to anonymous access?
Short of securing the Web interface down to a specific subset of users (I see no issue with securing the added functionality to logged in users), are there any other strategies on securing a Web service in this scenario? Am I just overlooking something obvious?
Require an authenticated session for both the server-side page and its caller via ajax, with both behind HTTPS.
Another strategy is to use a token that is bound to the session during the last page load to confirm that the session itself has not been high-jacked. This is done when the client loads the page. The server tracks what the next token must be to confirm a valid request.
I am working on an app that has several clients - Desktop, Mobile Device, Web Portal. We're moving to an SOA kind of architecture and will be using WCF.
The WCF story is great when it comes to using netTcp+transport/message security+Windows authentication (or even UsernameToken and a custom UsernameValidator provider) on the Desktop and Web Portal side.
Where it totally breaks down is on the compact framework side...the subset of WCF it supports is so limiting. I was resigned to simply using basicHttp + Username/Password in the headers all over SSL, but it seems that you cannot add headers when on the compact framework stack (no OperationContextScope) - so that leaves me with including username/password as parameters for EVERY SINGLE operation method in the service.
Please tell me I am wrong and there is a better way.
Your best bet is going to be to expose a WCF end-point that conforms to the WS-Security standards.
You should then be able to use those standards for message based security (most likely using X.509). Here's the MSDN link to get started:
Messaging in the .NET Compact Framework
An alternative solution is to pass a ticket (read: guid).
The client logs in (sends username and password). A randomly generated ticket is generated (guid again), cached on the server, and sent back to the client. This ticket is then passed back and forth instead of the username and password.
Of course, all of that is assuming you don't just want to utilize session state.
But in other words: I've had the same problem you've had. It sucks. This is how I got around it a bit so it was usable.
Anyway, another good reference is the WCF Guidance for Mobile.