Approaches for requiring forms authenticated users when calling a WCF restful service? - asp.net

Wondering about how to do the following efficiently, securely, and in a fashion that won't have us tearing our hair out because of overcomplication: we have an ASP.Net site that uses forms authentication and would like to implement some WCF restful web services that can be called from the first site, provided the user calling them has been authenticated.
We'd like to host the WCF RESTful service in a different web site from the ASP.Net site. Both sites will be in the same domain (my-domain.com for instance).
I've been reading up on the various bindings in WCF and am not sure if webHttpBindings are the way to go here (they being the most REST-friendly, but can they accommodate forms-authenticated users?)
I'm looking for suggestions and references as much as code, but I'd love to know where to start and what to look for, what's possible and what isn't.
Every time I read about WCF authentication it seems to inevitably sluice into discussions about WS-security and X509 certificates, and I don't know that I need all that for what I'm doing? What I'm really looking to build is a series of WCF restful services that only respond to forms-authenticated users. If that's not possible without diving deep into WS-Security and X509 then so be it, but I'd like to keep it as simple as possible.
Note: I asked a somewhat similar question about a month ago, but have decided to go with forms authentication.

If you are not calling your WCF services from the browser, then you don't even need to secure them. Just call them from your ASPX code to a non-public site that hosts WCF. Or use X509 certs in a server-to-server mode.
If you do plan to call them from the browser, then things get more complicated. In this case, you may want to ditch WCF and look at with Web API included in the MVC 4 beta release to build your REST services.
http://www.asp.net/web-api

Have your javascript generated from the code behind. If Page.User.IsAuthenticated, render the ajax script. If not, render javascript that alerts the user that they need to be logged in. If you don't want the user cutting the javascript out of the browser source and running it later, when they are not authenticated, you will need to generate a token based on the session ID, that can be passed between the site and the service.

Related

Constrain clients to ones coming from the own app/website for unauthenticated web API

These are the criteria:
My users are unauthenticated.
My app is a single page web app (written in JavaScript) that uses RESTful web API endpoints to fetch data from my own server.
Objective: I'd like to constrain the web API to only allow requests from my own app, without requiring users to authenticate. Are there existing techniques for this?
The issue is that since the web app's code and the requests made by it are transparent to the client it can't hold a secret for authenticating with the server.
I thought about creating single-use access tokens on the server side, then use those from the client side for the API calls. Now this would make it harder to do requests from the outside, but still you could make requests if you fetch this token from the original website first (even if you'd have to do it for every request).
If it matters I'd implement this with an ASP.NET MVC website and ASP.NET Web API endpoints.
Similar to this question but not entirely the same.
Thanks in advance.
I asked pretty much the same question a couple of years ago, and for unauthenticated users, some kind of token is pretty much going to be your only option. It doesn't make it impossible to get unauthorized access to your API, but does make it a little more painful.
I took a slightly different approach in my solution, using 2 cookies to protect some anonymous GET requests. One of them was the anonymous identification cookie, which was used as an encryption salt for another custom cookie given to the page that delivered the javascript. Only when the API request received both of these cookies and the decrypted result was satisfactory did I allow the WebAPI to respond. But like I mentioned, this only makes it more painful to gain access outside of the javascript app, not impossible.
Here is a reference for using tokens in WebAPI: http://codebetter.com/johnvpetersen/2012/04/02/making-your-asp-net-web-apis-secure/

ASP.NET web service using forms authentication from a windows app

I have an ASP.NET web service that I can access via a windows program but now I want to secure the web service. I can secure the web service using forms authentication. How do you access the secured web service from a windows forms application?
Although this is not the right approach, tt is theoretically possible to use forms authentication in the manner you describe. This could be accomplished by either:
Using a WebRequest to send your requests in raw form to the web service. This will involve inspecting the response, extracting the relevant forms-authentication fields, and sending a response back which logs the user in. This will generate a cookie which you must send along with each subsequent response to the service
Generate the FormsAuhentication authentication cookie yourself. This is complex as it involves synchronising the machine key on the calling application, and artificially manipulating the headers being sent to the machine hosting the service.
Display the forms-authentication form for the user to log in to at the beginning of a session requiring interaction with the web-service. You can then harvest the generated cookie and present it to the service in HTTP headers as in option (2).
As you can see, these methods are highly complex, and are fundamentally a hack to use forms-authentication where it was never intended.
Microsoft intended us to use either Windows authentication, or SSL certs to secure access to ASP.NET web services. See HTTP Security and ASP.NET Web Services on MSDN.
If you are able to use WCF, then a few more options present themselves, including the ability to build a custom authentication mechanism into the SOAP, with some support from WCF.
For the most part, securing web services is one of the trickiest parts of the job. Many live solutions which I have seen are compromises such as the ones above.
It seems the answer is no. Forms authentication is a cookie-based mechanism, and your WinForms app won't be able to hold and relay the cookies (without some serious workarounds, if at all).
A potential workaround that I wrote up when researching your question attempted to use a NetworkCredential object, but that didn't work. Also tried was the ClientCredentials in .NET 4.0.
var ss = new MySecureWebService.MyServiceSoapClient();
ss.ClientCredentials.UserName.UserName = "abc";
ss.ClientCredentials.UserName.Password = "123";
string asmxReturn = ss.HelloWorld(); //exception returned here
The console app was still presented with the login html page when calling the webmethod.
Other Suggestions
If you have the source to your web service, extract its logic out into an assembly of its own. Reference that assembly in your WinForms app, and it's just as if you're calling the web service.
I understand that your goal is to reuse the app that's deployed, but the next best thing would be to use the same logic/implementation via .dll reference.
This might help: http://dotnetslackers.com/articles/aspnet/Securing-ASP-Net-Web-Services-with-Forms-Authentication.aspx.

Constrain the consumption of a web service to certain apps

Is there a way I can configure my asp.net web service to work with only some applications? In other words, I am saying "only these applications have access to this web service and can therefore use it. Others can't".
When other applications tries to discover the service, it shouldn't even show up, or at least it should conceal it web methods.
PS: I am wondering if this scenario is even applicable to the whole concept/domain of web services? Plus, I am asp.net 2.0 oriented, but you can give me answers based on higher framework versions, but be specific...Thanx in advance.
I'd look at WCF (after all ASMX web services are now regarded as legacy)- there is a whole load of options regarding security configuration. Patterns and Practises have Security Guidance here. It sounds like you are most interested in authorization, so read about Access Control Mechanisms.
Also to make the service non discoverable in WCF you just don't expose a MEX endpoint. That doesn't stop clients connecting, but makes it hard for people to work out how to call the service. That said you can also secure the MEX endpoints so that is another option.
Can you put some authorization or login method to initialize usage of webservice?
We control usage of services by explicitly logging into the webservice or provide some authorization token.

Least intrusive way of securing a web service?

I am maintaining a public website (no authorization required) that uses web services over https to perform various operations. Most of the calls to the web services are invoked from javascript.
What has recently occurred to me is that a malicious hacker could, if he/she chose to, call the webservices directly in an attempt to play havoc with the system.
In reality, there is not much damage they could do, but in practice these things are difficult to predict.
Bearing in mind that the web service calls will be exposed in javascript code (which is available to the client) what is the best approach I could use to prevent unauthorized and/or malicious access to the web services.
Sadly, I can't just restrict access by IP, as there are windows forms-based client applications out there which also interact with the web services.
Using windows authentication may be difficult, as these client apps can be run from anywhere in the world and the users are not part of any specific AD Group - or even domain for that matter.
I'd appreciate any suggestions, bearing in mind the two different classes of access and the exposure of the javascript code.
Anything called by javascript can be mimicked easily by a malicious user who has the right to use that javascript. I would suggest modifying the page to use a more server-side solution. Leave AJAX to stuff that can't be easily exploited.
Preventing an unauthorized user is MUCH easier than supporting full public access. If you drop a time-expiring guid on the user's cookies, tied to the individual user, that gets sent as one of the arguments to the Web Service, you have an extra, generally difficult-to-break, layer to the application.
Anyone who has access to execute the javascript, though, should have no trouble piecing it together. Someone who has no access to the javascript can probably be kept from accessing the Web Service easily.
It takes a bit of doing, but if your page is also ASP.net you can set up a shared session, turn on the EnableSession attribute on your webservice and use session data to secure the session. An overview can be found here: http://blogs.lessthandot.com/index.php/WebDev/ServerProgramming/ASPNET/sharing-asp-net-session-state-between-we
This would necessitate a different "version" of the service for your windows apps to consume.

Best authentication mechanism for Flex, ASP.NET and SOAP or REST web services?

I am building a web based application written in ASP.NET and Flex. One of my biggest challenges is implementing security for the application in a flexible and maintainable way. This challenge is compounded when different technologies are involved. I'll try to describe what I have below.
The website is laid out as follows:
/mydomain.com/
Login.aspx
Default.aspx (hosts flex [.swf] application)
/Administration/
AddUsers.aspx
AddRoles.aspx
AddPermissions.aspx
etc...
/Services/
SecurityService.asmx
MapService.asmx
PhotoService.asmx
etc...
I am currently using forms authentication to secure the resources on the website. All pages/resources not in the /Services/ folder require an authenticated user and will be redirected to Login.aspx if they are not yet authenticated. The .asmx pages allow unauthenticated users. To secure these resources I throw an exception in the SOAP method. This avoids redirecting pages for SOAP web services which is not supported by any SOAP web service clients I am aware of. Finally, SecurityService.asmx contains a Login method to allow the Flex application to Login without redirecting to the Login.aspx page should the cookie expire for any reason. Because the cookie established is sent with any request to the server, including requests coming from the Flex application, this seems to work pretty well.
However, this still feels like a bad approach securing web services. I feel like I am using Forms Authentication for something it was not intended for. Specifically, I am concerned about:
This model will not work when the services are separated from the core website. This is a newly discovered requirement and I believe that Forms Authentication is not going to work well (if at all) without a lot more modification and trickery.
Clients other the Flex may require access to the services. Some of these clients may not even be able use cookies. If so, this model immediately falls apart. This is not an immediate requirement but it is known that this is one of the long term goals.
We will eventually (hopefully sooner rather than later) move to a REST based architecture (vs. SOAP) so any solution needs to work for SOAP and REST.
So, my question is.
What are the best authentication and authorization mechanisms for securing an application built on ASP.NET, Flex, and SOAP or REST web services?
Note: I am actively looking into OAuth; however, I am having a difficult time finding complete examples from which to learn. Additionally, I need to be able to filter the data returned for a given user based on the permissions that user has, OAuth seems to remove the identity of the user from the token. As such, I am not sure how OAuth applies in a fine grained security model.
Others may disagree, but I actually don't see a huge problem with handling it the way you are now; that's probably how I'd handle myself, at least initially. One way or another, even down the road, you'll probably want to keep the Flex app aware of the authentication state of the session, so if that means checking the ASP.NET session token directly, or some other cookie you set when you set that one, it seems like a fine and reliable way to go.
I do see what you mean about the services redirecting, but even so, with forms auth, it's not so much the service specifically that's handling the redirecting so much as the ASP.NET app itself. Later, should you need to use a different authentication scheme, you can consider that scheme's specific implementation considerations. Unless you've got concerns about using forms auth in general, there's probably no need complicate your approach simply because of the Flex client and Web services.
I admit I don't work with web services much, but what about requiring an access key as a soap header parameter? Any client app which can communicate with a soap web service is likely to have a low level API to modify the soap request, and use of the access key allows you to (in theory) limit the use of the service. Google, Amazon, and several other providers use this type of authentication for their web services and it seems to work very well.
This article seems like it might be a good place to start...
The WCF Security Guide published on CodePlex may help you there, if you are using, or can use WCF.
There's also Microsoft's Web Services Enhancements (WSE) 3.0 which I believe implements some of the WS-* security specifications.
Hope that helps.
If you move your services to another place, then the standard ASP.net authentication cookie can be re-used if both web apps have the same machineKey in the web.config.
As far as I know, FLEX will honour the asp.net authentication cookies because it will make http requests through the browser, which will pass the http cookies (including the asp.net authentication ticket) like a normal http request.
Have you tried securing your website and services using normal asp.net authentication yet?
I think it's best to have independent authentication systems - even if there are relations between the user and the auth tokens on the back end. They are different beasts that have differing capabilities and demands.
Use the normal forms based auth for the flex portion. That is good.
For web services, you could create a login method that returns some auth token which is used by subsequent tasks to execute. Or add a few fields to your web services (posted in the header or as params) to use a userid/password combo for authentication each and every time.
A side note: I wouldn't rely on a soap exception to handle authentication problems. But you wouldn't need to worry about the redirection if you send an auth token or user/pass with the WS requests.
EDIT:
RE: Comment-
Ideally there is. There are products out there (Tivoli access manager) that service those needs, but they are expensive.
I gave this recommendation because it eases the pain of allowing access to alternative clients and as long as you designed the services correctly it's stateless. It also gives you finer grained control over data level access on the service side of things.
See Web Services authentication - best practices?
Dave Dunkin wrote:
The easiest way to handle it across a
variety of platforms is to use HTTP
basic authentication and HTTPS for the
transport layer. WS-Security would be
good if your needs go beyond simple
username/password but the support is
going to vary quite a bit between
platforms. HTTP authentication is
supported by every decent SOAP
implementation.
and my Custom HTTP Basic Authentication for ASP.NET Web Services on .NET 3.5/VS 2008.

Resources