ASP.NET authentication for custom API - php

I know this is a pretty discussed topic but i'm struggling in finding a solution for my case.
I have done an already working API service in ASP.NET (c# 4.5.1). My clients uses php pages to call a page.aspx on my server and sending via POST a string. This string contains an ID and a cypher message. Every user have a different key (AES 256) and, since i have the ID i get from my DB the correct key to decypher the message and do what its request contains. I also check the IP, every client have only a list of approved IPs (when they are not using the debug mode for testing)
I like this method but now i have to let my users do some purchases. I already implemented it (thank you PayPal) and it works, but i feel my security weak.
So i wanted to add some already known and already wrapped authentication system, without re-writing any of the already working and debugged code.
Since is used from lot of big internet services i thought about OAuth 2.0 (and i know nothing about it), but looks like everyone who talks about it is for creating a login that uses services like Facebook, Google, Twitter and go on.. not my case. I have my own database with my user list and i need to know with 100% security who is calling my API service.
I tried creating a new Web API 2 project (MVC.. damn) but i cannot understand if i can use for my service without rewriting the logic for API calling (and from what i saw looks like no is the answer)
So the question is: What authentication method can i use that is easy to implement without rewriting the already working code and can be usable from clients with PHP?

I was watching "ASP.NET MVC 5 Fundamentals" tutorial on Pluralsight by Scott Allen where he explains it quite nicely. But before watching that tutorial, for one App I worked on, we had a table in the database with tokens that were issues at Login. Then the client would send the token with their request. At server side, I did a custom attribute called [CheckToken] inside which I would check if the token exists in the database and if it is stil valid (not expired, etc.) I went a step further and sometimes swap the token so that even if the token gets stolen, it would not be valid for long. That way, the user does not have to keep login in all the time.

Related

Symfony2 RESTful API + AngularJS

I've been working on an e-commerce project built on Symfony2 (for the backend) and AngularJS for the frontend. Currently the Symfony part is used only as an API, which has three different user levels (guest, customer & admin). Different actions that can be done within the system (like add/remove data) are secured by:
Symfony2 firewall with user roles/access control
JMS security extra (#PreAuthorize expressions)
For the parts that are secure everything works as intended and I'm very happy with the way things work.
Problem:
There are parts of the API which are public (like retrieving product information, categories, etc.). I'm retrieving such data in Angular with Ajax calls to my API that returns the data in JSON format. One example would be:
/api/product/get-all/?page=1&count=10&sorting[id]=asc
The problem is that anyone could look at the requests in browser and copy the path and have access to all the data (such as all the products) and could just download a JSON of all the information. Although this data is "public", I don't want to give others such an easy way of "stealing" my data.
Ideas & possible solutions:
I was looking at the JWT (Json Web Token) standard to try and secure the public calls to my API and implement it in such a way that I generate a token for "real" users that are on the website, and such limit direct access to public API links.
What do you think? Would this be a possible solution?
I was also reading in some other question on StackOverflow that I could check the HTTP_X_REQUESTED_WITH header from the request, but we all know this can be easily spoofed by an attacker.
Finally, I read a similar approach to "solution" 1) here : http://engineering.talis.com/articles/elegant-api-auth-angular-js/ but I'm not entirely sure that this fits my purpose.
Additional notes:
I don't want to make this bullet-proof, but I also don't want to give people the option to click 2 buttons and get all my data. I know that eventually all the information can be "stolen" (e.g.: by using a web scraper ), but "securing" the system in such a way that people would have to make a bit of an effort is what I have in mind.
I can't really re-model my API too much at this stage, but any ideas would be appreciated
Thanks for taking the time to read my question and I'm looking forward for any feedback.
You can limit the abuse of your system in a number of ways, including:
Limit the total number of requests that API will return before requiring CAPTCHA or some other validation method. This can be limited by IP, browser fingerprint, authentication token, etc.
Make it difficult for abuser to guess IDs of products, categories, etc. by using GUIDs or other randomly generated IDs.
Use API management proxy such as Azure API Management for more enterprise level management of the APIs (http://justazure.com/azure-api-management-part-one-introduction/)
You could try something like:
To access the site anonymous users first need to fill in the captcha to get temporary token.
Add referrer check on.
Limit amount of data anonymous users can view. For instance, first 50 products.
This way everyone who wants to steal your data first need to get anonymous temporary token by filling in the captcha and change referrer.
Try with DunglasAngularCsrfBundle

RESTful API Auth flow

I've been on stack overflow for the last hour researching this topic so I thought I'd just ask all my specific questions. I'm building a web app currently using Laravel (PHP) for the API and Angular for the front. I've looked at oAuth but it's a little daunting atm so I was hoping to implement a simpler solution and then rebuild it in when necessary.
The flow I'm currently implements goes as follows. Angular posts the user credentials (over https) to my rest backend and this simply returns a generated string (this will probably be random or crytographicaly generated). This string is then stored as a cookie or whatever browser state I find suitable and then attached to every API request along with a user id that angular makes as an extra parameter or request header or something. The API uses this to check if the user has access to the requested resource and responds accordingly. I'd probably also add a expiry time on the string which would be reset after every request.
My question is really if this is an acceptable flow? In terms of security what issues am I most likely to face with this? CSRF? Session fixation?
I know this is a question that's been asked a couple times before but I was just hoping for a fresh discussion and be pointed towards relevant information.
If I'm understanding you correctly, this is a model I've seen in plenty of APIs, especially in the stateless SOA world. The "string" you're talking about is most commonly referred to as an "auth token." And all non-public API methods require the token (and for it to be valid -- expiration is essential, else someone could grab an old token) to be included with every request (with or without username -- the token should be uniquely identifiable so as to make that unnecessary, but it doesn't hurt), which means before you do anything you have to call the Login API (which does not require a token, natch) to get one before you do anything.
You may want to have your token's expiration refresh on every use (idle timeout), or else you will need to have your clients know they may need to refresh the token (i.e get a new one) every once in a while (which is somewhat more secure than an idle timeout one).
What you describe is some kind of basic session implementation. Since REST have a stateless constraints which denies such things, I don't think that this is an acceptable solution. Afaik you have to send the username and password with every request from the trustable clients. If you have 3rd party clients, then you have to generate api keys and access tokens for them (OAuth can solve that part). If you want to know more about REST constraints, then read the Fielding dissertation.
Thanks for you input everyone. Ultimately I decided to have a look into OAuth 2 again as suggested. What I was trying to create was pretty much an OAuth flow anyway... Instead of trying to recreate the wheel I looked at other people's implementations of OAuth in PHP (and Laravel) and this practical implementation really helped me get the idea.
I used this package in the end
https://github.com/thephpleague/oauth2-server
Wrapped for laravel
https://github.com/lucadegasperi/oauth2-server-laravel
I was a bit unsure about how OAuth would be implemented for my use case as it was just for internal usage. I discovered that because I had a high trust of the client a great flow to use would be the Resource owner credentials grant.
The only real issue I face now is securing the client id and client secret. It being stored on client side is definitely an issue but form my understanding that's just one of the issues of OAuth. Fortunately if it's ever compromised I can revoke and reissue.
Anyone else that comes across this with a similar question should have a look at the following links:
http://alexbilbie.com/2013/02/a-guide-to-oauth-2-grants/
https://www.rfc-editor.org/rfc/rfc6749
They really helped me understand OAuth 2.

Restful App making SAFE CRUD requests to the server using php laravel

Question may sound similar to a lot of information thats under Resful Designs.
I've read numbers of articles went through bunch of tutorials, trying to understand how Resful apps work. I see bunch of tuts. Looked into OAuth but it is not what i need..
Since security is my main concern, I have come to problem of how i should be handling nonces/hashes!??
What do i mean by nonce/hashes is;
I have a Restful application which uses laravel 4.1. Framework, users can log in with Auth::User() implementation. All is good. ALL REQUESTS I make to the application are CRUD.
Why Do I want to use nonces/hash;
Lets i have #DELETE Route("workouts/{id}") under api prefix in my resource
users can delete workouts using example.com/api/workouts/1 does it not has to have also something like {nonce} attached to the link like example.com/api/workouts/1/nonce/12321321313 since everyother user may fake redirect user and make a person delete its own workout?
Most of the Articles indicates that;
As far as I know for security concerns, I should be sending a nonce along with every ajax request to the server, then server must verify and respond back to the client with informations along with new nonce for the next request? This is a performance killer but is it the way?
HTTPS REQUESTS?? NO TOKENS/hashes or nonces?
So some say Under HTTPS PROTOCOL after logging in safely(valid credentials) there is no need to send a nonce ( to the server) for each request (such as CRUD) anymore. Authentication with credentials is enough to authenticate user for goods.
Looking Through all of Laravel angular tutorials
There is nothing mentioned about using tokens nonces or anything at all, at least not that I've seen of.
My main question is how I should be designing server side routes to make safer requests to the server with laravel using tokens, nonces or hashes etc?
I know there lots of topics but they seem very theoric to me. I dont know which are accuratly protective and which arent. So thank you for your patience of reading it and hope to gets some accurate response..
and excuse my English :)..
I believe that using the term RESTful application is a bit misleading. But, if you using a REST API you should have a look at JSON Web Token for authenticating users to your API.
Some helpful links here: JSON Web Token, and a Laravel package jwt-auth and an Angular example, keep in mind that the Angular example is with Node.Js but it can be integrated with Laravel.
If you are using just AJAX requests to PHP scripts for CRUD why not use a package for protecting against CSRF attacks for Laravel, just google it and you find more tutorials.

Access database securely from iOS App

I chose MySQL after looking between MySQL and SQLite for accessing because my iPhone app needs to pull information from an online database that is already in MySQL.
I believe the traditional way of accessing information would be: To have a php file on the server that does the accessing for you.
The iPhone app would call this php file and it would return the results.
iOS app will call http://somewebsite.com/index.php?id=234 and the website would print out the username of id=234.
Now, how secure is this process?... I would obviously use prepared statements and https. But what if someone found the URL for this website? How do I protect myself against misuse (someone could generate a list of all my users)? Is this the standard way to have your iPhone app connect and get info from a database?
Edit: Furthermore, lets say I needed to create an app login page... I have a MySQL database with username and password (hashed obviously). Would it be safe to use $_GET variables to see if they are authenticated. Like for example: https://somewebsite.com/checkauth.php?username=test&password=C3LyiJvTCQ14Q and have the php print out yes or no. Picture examples below:
I would assume the above method would not be safe to do... but I need to be enlightened.
Also, I'd prefer to stay away from calling the database within the app using third party API, not supported by Apple.
The best way to go about this would to setup an API to interact with the database on the server and your iPhone app just queries the API and returns the data in a machine readable format such as JSON, see http://en.wikipedia.org/wiki/JSON and http://json.org/. So for user login the server would return maybe something like:
{
"result": false,
"error": "Invalid username or password"
}
This would be generated by PHP with the following code:
echo json_encode(array(
"result" => false,
"error" => "Invalid username or password"
));
Also note that, you should use HTTP response codes in conjunction with this, eg 401 for unauthorised.
JSON can use boolean and other data structures within its format. Nearly all major languages have support/libraries for it.
The benefits of this is that it allows you to build other applications using the same API such as an android version or an actual website.
This SO question is a good starting point on the security of mobile applications:
Creating an API for mobile applications - Authentication and Authorization
The main points are make sure to use HTTPS. When sending over user credentials you could return a user token (api key) that can be used for future requests and stored within the iPhone app for future access.
Eg: https://iphoneapp.com/notifications.json?key=98fy92473r92hAAIYEFG397qbqwiuUEAF
Your key should be sent in a HTTP header or in the POST so it is not recorded in logs etc...
Note: This is just a random string typed on the keyboard.
This method allows you to delete/regenerate the key if it gets compromised. You can also set rate limiting on the keys and various other parameters.
Another huge benefit is by building an API that your own app uses means that it will be maintained to a high standard and other third party companies can also use the API (if you allow them).
Edit: Furthermore, lets say I needed to create an app login page... I
have a MySQL database with username and password (hashed obviously).
Would it be safe to use $_GET variables to see if they are
authenticated. Like for example:
https://somewebsite.com/checkauth.php?username=test&password=C3LyiJvTCQ14Q
You should send that sensitive data using POST instead, but any service has to login at some point. Using HTTPS should help the most as it prevents eavesdropping. After the first authentication you can return the token and reap the benefits mentioned above.
As for the user login as along as your PHP conforms to good practices you should have no issues. See http://www.phptherightway.com/ it will help a lot if you have questions.
Definitely research OAuth and utilize that if you can/want to.
This is just a starting point and is NOT meant to be used word for word, further reading and googling is required.
If you're looking for an alternative to a "build an API from scratch" approach we've used a web based service called Kumulos available at kumulos.com for a quick and easy solution.
This service allows a developer to connect to a MySQL database and build the data model and APIs via a web page then deploy a native library to your platform. I believe you can also import an existing data model as well.
Once the data model is built on the web page you can then build APIs and specify input and output parameters. The APIs are modeled based on the type of SQL operation you are performing such as SELECT, UPDATE, INSERT, DELETE.
In your case you would want to model a login/authentication UI which accepts the username and (hashed) password, validates the data against the Users table and return the authentication results.
Once your APIs are modeled via the web page you can then "deploy" your configuration and generate native libraries for iOS, Android, PHP, and others.
The generated Obj C library gets dropped into your project and you make and respond to APIs using objective c calls and delegates.
Kumulos includes some other features as well like data export, API call metering, and what they call KScript. This is essentially the ability to wrap your call in javascript at the server (also configured via the web page) to greatly expand the flexibility and capability of the API call functionality you can build.
We've had a couple of questions or support issues over the past few months and their support has been top notch. Their backbone is on Rackspace. We've got about 8 or 10 production apps running APIs through them at the moment and are quite satisfied not having to hire an API developer :)
Many mobile applications use APIs to get and store information in servers. Figuring out some of these endpoints is not complicated, and having unsecured endpoints returning sensitive information is a dangerous thing to do.
The first level of protection of your API could be to create an "API key" that identifies the application. This key is stored it in the server and checked on every request. Request with no API key should return a HTTP 401 (Unauthorized) status code.
API keys are okay, but insufficient when some calls can only be performed by certain users. For example a user needs to update his information, only the owner of the information should be able to perform this call, and not another user. For this you can pass authentication information that identifies the user to perform the update action.
I do not recommend using username/password on every request, instead have the user authenticate once, and let the server send back authentication tokens that can be used by the application to perform future authenticated calls. Take a look at OAuth2 as a potential Authorization Framework. Also check out OAuth 2.0 - The Good, the Bad & the Ugly.
I suggest using BShaffer OAuth2 Server in PHP. Also see Best Practices for securing a REST API / web service for alternatives.
From your question it sounds like there is an existing subsystem, I recommend creating a simple interface that makes the subsystem easier to use, and reusable across multiple clients instead of modifying the subsystem to accommodate an API. This is commonly known as a Facade Design Pattern.
Many PHP Frameworks have packages to implement custom RESTlike APIs. Symfony has FOSRestBundle, FuelPHP has a REST controller out of the box and CodeIgniter has a REST server.
To summarize:
Create a simple interface to access information from the existing system (a REST API).
Protect your private information using a proper authentication mechanism (maybe OAuth2).
Use existing libraries and/or frameworks to speedup development.
Your code will be reusable across multiple applications and platforms as a result!
if you want to access database from IOS Application and save data into database you have to use middleware solutio.
which is Webservice
Create Web Server In Microsoft ASP dot Net And Access That WebService in IOS Application With that you can communicate between two different OS.
return from Webservice is XMLdoucment which can be further parse with xml purser.

Sign on several sites

i have 2 sites (example.com, ex2.com). Fisical is a 1 site with 1 db. When user sing in ex2.com, he was sing in example.com too. How do this?
P.S. Can do this with ZF?
I found a very interesting article on this topic. The author gives some ideas how to implement Multidomain authentication.
http://codeutopia.net/blog/2008/09/25/sharing-authentication-over-multiple-sites-single-sign-on/
Have you looked into OpenID? You could lock OpenID consumer "ex2" to allow logins only from your "example.com" OpenID provider.
I am also digging the subject. Some time ago, I already did my own implementation and got it terribly wrong.
At the moment I am wondering whether to setup an own OpenID provider and locking consumer sites to accept only it. Another alternative would be yet another own implementation with a CAS style setup, where only a hash is passed via the browser, and the user verification is done server-to-server in the background using the hash as a disposable key.
I am not yet sure which one to pick or would some third alternative be better.
You could take a look into something like http://cosign.sourceforge.net/. Cosign enables you to create a single point of login for multiple sites. It's not specific to Zend but should work.

Categories