I have a bunch of websites that are setup identically to use a WIF identity provider. I've recently moved the business logic out of the web applications and into a Web Api service application. This runs in a different virtual directory to the other sites. The idea being that browser will put the data into the page AJAXy.
The issue I have is with securing the web API. It seems that WIF single sign-on works okay with traditional sites. The user can access one website, get redirected to the identity provider, login and get redirected back to the website they wanted. When they access another site they also get redirected back to the identity provider but needn't log in as a FEDAUTH cookie exists so they automatically get authenticated and redirected to the second site.
This doesn't work for the Web Api scenario because when the browser perhaps makes a GET to it, the Api will return a redirect to the calling javascript when it should be expecting JSON.
Is it even possible to secure Web Api with WIF?
Not sure whether I got you right, but it seems like the main problem is that javascript/ajax does not support http redirects.
A possible solution could be to simulate the redirection with a sequence of seperate calls in ajax:
Check whether you are authenticated on your web api site (by a dummy ajax call).
If this is not the case:
Call your sts over ajax and grab the security token out of the "wresult" form field.
Call the login site on your web api site and pass the security token as "wresult" data.
Dominick Bayer wrote a few blog posts about securing rest services. For further reading have a look at http://www.leastprivilege.com/. (Especially http://leastprivilege.com/2009/09/11/adding-a-rest-endpoint-to-a-wif-token-service/ and
http://leastprivilege.com/2010/05/05/thinktecture-identitymodel-wif-support-for-wcf-rest-services-and-odata/).
The following presentation from TechDays might also be interesting: http://www.microsoft.com/showcase/sv/se/details/ffc61019-9756-4175-adf4-7bdbc6dee400 (starting at about ~ 30 minutes).
Related
I have a website in IIS say abc.com
Now i also have a asp.net API as virtual application within abc.com
I want to restrict all direct access to the API , except from the website.(browsers, postman, fiddler , etc)
Within the API, I tried to detect ip from which the request was made
context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
context.Request.ServerVariables["REMOTE_ADDR"];
Although the above may help detecting client ip , it may do little to help in preventing outside website request to the API
How can I accomplish this?
Thanks for any pointers.
Does the web site require logons, and did you implement security? Any web service call (to a static method in a existing aspx page, or even a call to a asmx page? if that page is placed in a folder that has security (in web config, as normally dropped in each folder to secure by security groups (roles)), then those web service calls from the browser simple will not work unless the user is logged into the site correctly.
For any web calls that you don't need or want security, place those aspx/asmx pages in such folders without IIS security applied, and no logon will be required to use such pages.
If you don't' have any security setup? Then it going to be rather hard to suggest you want security for the web site when there is no security setup?
So, even a simple basic FBA (the classic security setup) will thus be handled by IIS, and those web service calls can't occur unless the user is already logged in. So, your free to write and setup ajax calls from the client-side page, and you don't even have to worry about security in that client-side JavaScript code if the site has security setup.
If you don't have any security setup or applied to the site, then it quite much suggests that you don't have many options in the way of security choices.
I am very new in web api security. I have used form authentication technique. when user logs in, a token is created and stored as a cookie in user's web browser. On each request the token is varified and if user is authenticated and authorized user is given access to the service.
but I think this approach does nothing in web api security. cookies can easily be copied and pasted in other browser and anyone can get the service.
I am thinking to use App key and secret along with form authentication. I am not suggested to use third party service like Oauth for authentication. I am not Sure about the Implementation of app key and secret that how it exactly works.
Please provide better way to secure my web api wihtout using third party services and to prevent cookie hijacking etc. What actions are performed to build a strengthly secure web api.
The forms authentication is good enough. You can also do the following:
Use anti-forgery (antifrogery) tokens. Check this or this
It will also be great if on sensitive actions you check if the call to the function was made from the same site or not.You can implement your own action filter for this. (check if the referral site is your site, or the expected site)
Edited:
Thanks guys for your comments. I guess you are right. Well authentication cookies in ASP are created as httpOnly cookies which means even if the site had some XSS vulnerabilities it will still be safe and cant be stolen. I would also suggest to use https everywhere if the site is used for sensitive operations (like a bank) to make sure the cookies are perfectly safe.
Here's the situation, I've got a console application that needs to run once a day and make a few requests to pages that require authentication to view. The pages are hosted in a really basic ASP.Net Web Application.
So, I know that in order for the requests to go through successfully I have to authenticate with the server. So I've hooked up the console application to the ASP.Net Membership Provider I'm using for the web app and it successfully determines if a set of a credentials are valid. However, after calling Membership.ValidateUser() any requests I make just get the login screen. After doing some reading it seems that this is because I'm missing the important cookie information that persists my login or what-have-you.
I'm using a basic WebClient to make the requests and then reading/discarding the result.
So the meat of the question is this: Is there a simple way to validate the login information and hold on to it so that I can make the requests successfully, or is this the exact same case as the other two questions I found that require the WebClient to make a "manual" login request to the login.aspx page and try to hold on to the cookie from there?
The questions I'm referencing are:
Authenticating ASP.NET MVC user from a WPF application
and
Login to website and use cookie to get source for another page
With FormsAuthentication the webserver has to generate a Forms Authentication Ticket for you. The best (only?) way to do this is to log into the site, so I'd just log in like the other questions.
If the intent is to send data to the server and/or get data from the server, then the most logical architecture is probably to create a web service using either ASMX or WCF. Then configure the service to use a security token, such as a username token or a SAML token. This will make the client less likely to break when the server code changes its data model.
Otherwise, if you wish to use only a basic WebClient, then you will have to find a way to pass your credentials to the login page and retain the login cookie that is returned from the login request. Then, make sure that the login cookie is included on all subsequent requets, similar to the Stack Overflow question that you referenced, "Login to website and use cookie to get source for another page".
HI have the following scenario:
1) i'm authenticated against some aSP.NET web site and my session time out expires in 24 hours.
2) after several time I would like to run query against asp.net Web Service located on the site using existing authentication.
What should I add to cookie Container? I how do sent existing cookie to Web service?
Thank you in Advance.
Danny.
A web service call is just an http call so it will come under the existing authentication.
I am assuming here that you are issuing this from the browser?
If not - e.g. if you are doing it from a console application, then you will have to interact with the site as if you were a user. Some more details are her http://www.ksingla.net/2006/08/sample_forms_authentication_test_in_csharp/
Basically you need to issue a post to login to the login page - track all of the cookies etc - and then start issuing your WS calls with those cookies.
Another option is here http://en.gli.sh/Blog/post/NET-Interoperability-Between-Smart-Client-and-Internet-Explorer-Using-Cookie-based-Authentication.aspx which is reading the correct cookie info from the windows machine you are on - relies on you being logged into the website and also trusted to be able to get to that file.
Alternatively you can look into implementing WSE or WCF solution.
I've built an application that uses jQuery and JSON to consume an ASP.NET .asmx web service to perform crud operations. The application and .asmx are on the same domain. I dont mind people consuming the read operations of the .asmx remotely but dont want people randomly deleting stuff!!!
I can split the methods i'd like to be publicly accessible and the 'hidden' ones into 2 web services. How can I lock calls to the 'hidden'.asmx web service to the same domain that its hosted in?
Thanks in advance.
Edit:
Can someone comment on this, seems plausible ( source: http://www.slideshare.net/simon/web-security-horror-stories-presentation ):
Ajax can set Http headers, normal forms cant.
Ajax requests must be from the same domain.
So "x-requested-with" "XMLHttpRequest" requests must be from the same domain.
There are two scenarios you need to secure with web services:
Is the user authenticated?
Is the action coming from my page?
The authentication piece is already taken care of if you're using Forms Authentication. If your web service sits in a Forms Authentication-protected area of the site, nobody will be able to access your web services unless they're logged in.
The second scenario is a slightly trickier story. The attack is known as CSRF or XSRF (Cross Site Request Forgery). This means that a malicious website performs actions on behalf of your user while they're still logged in to your site. Here's a great writeup on XSRF.
Jeff Atwood sort of sums it all up in the link above, but here is XSRF protection in four steps:
Write a GUID to your user's cookie.
Before your AJAX call, read this value out of the cookie and add it
to the web service POST.
On the server side, compare the FORM value with the cookie value.
Because sites cannot read cookies from another domain, you're safe.
In AJAX the browser makes the calls, so even if you were to check that the domain is the same it wouldnt be secure enough because it can easily be faked.
You need to use some sort of authetication/autharization tokens (preferably with a time out) to keep things safe.
Quick and dirty solution would be to use IP address restrictions to allow only your domain's IP address access via IIS.
Probably better would be using HTTP authentication. There are many ways to do this, I found Authentication in ASP.NET Web Services a helpful overview.