I'm building an iOS app which will communicate with a set of .NET WebServices. I'm trying to find a way to ensure on the WS side that the calls being sent actually came from the iOS app.
There is, of course, a "login" method which requires a username/password combination. I would like to add a "security token" to this method, which I can use to validate that the request is coming from the iOS app.
Since this is a parameter to the login method, is must be something known by the app and the web service BEFORE a valid login occurs. Additionally, it should be something which is impossible (difficult?) for another application to fake.
Are their any best practices / standard methods for this sort of exchange? Am I even thinking about the problem in the correct way?
Thanks in advance!
Take a look at the oAuth specification (used by Twitter) it requires that a user is verified first, during the process a series of tokens are exchanged, and then the token is used to sign the data during subsequent data exchanges.
It works on the principals of public/private matched keys, so you have one key that is always kept a secret.
Related
I'm currently trying to setup FOSOAuthServerBundle with my Symfony2 app.
Everything seems to be setup and functional, anyway I'm stuck after the installation.
What is the proper workflow with URLs to get the access_token ?
I tried /oauth/v2/auth, but sounds like I need to define a Client object first.
How to create/generate Client ? Clients are always supposed to be created manually ?
FOSOAuthServerBundle doc is great, but seems to skip all the usage workflow. Am I supposed to check the OAuth2 doc for this ?
Thanks !
In short, yes. You should be using the oAuth2 RFC to determine which workflow you want to use. In regards to client registration the RFC specifically states that the means through which a client registers is beyond the scope of the specification (https://www.rfc-editor.org/rfc/rfc6749#section-2).
With that being said I can give you some insight into how I did this. My application is a mobile phone application that connects to several services running on various servers. I'm also using the Resource Owner Password Credentials Grant.
The way I approached this was: when the application loads, the first thing it does is to check if it has an oAuth2 client id. If it doesn't, then it POSTS to a create client endpoint I've setted up with the meta-data I need. The endpoint validates the POST, creates the client and returns the client information. The application stores the client id and the process doesn't have to be repeated the next time.
Application loads;
Application checks for oAuth2 client id;
If there is one, the process ends;
If there isn't, it posts to http://www.example.com/client;
If we get a 200, store the oAuth2 client id.
I could have also created the oAuth2 client when the user created an account in the application, but I wanted to make the registration process as fast as possible. Creating the client would have added some extra waiting time to the process.
Check this: http://blog.logicexception.com/2012/04/securing-syfmony2-rest-service-wiith.html
It's quite simple to convert to Doctrine, whether you use it.
There's a command-line that does exactly what you need: create a Client!
I need some good suggestions and ideas.
I have wcfRest service and the client is iPhone and Android. The client will GET and POST data.
I also made an API key which is a GUID, for the client.
BUT, do the client need to supply the api key with every method they request?? Or is there any way that I can store in the session or something??
for example:
json/getUserDetails/{userID}/{apikey}
json/saveUser/{apikey}
You could try checking out OAuth, that's the security method Twitter, Facebook, Google and others use. Since sending the API key to the server could lead you to someone getting it and doing stuff you might not like.
OAuth
An open protocol to allow secure API authorization in a simple and standard method from desktop and web applications. It also works with mobile.
http://oauth.net/
Also check out the different languages http://oauth.net/code/
You'll have to send something on each request - whether it's the API key or an authenticated header, you need a way to authenticate the caller. So the easiest way would be to send the api key with each request, although using the header is a better idea.
i'm in the early stages of developing an API for my site so that third party developers can build an iPhone application for it. The API would have a limited subset of the functionality of the full site. The trouble i have is around security and authentication for the user who downloads the application. I have come up with the following options:
The user enters the same credentials they use on the site to authenticate themselves. My API would then take the credentials when accessing information specific to the user. This is my least preferred solution as the third party application could log these details and use them maliciously on the full site.
Each user generates a unique key on the site which they can then use on the app to login. My API would take the api key as an argument when accessing information specific to the user. The main problem though is that any application can do what they like to the user once they gain access to their key even if the user has not given the application permission to do so.
To overcome the above problem the third party developer would have to register their application with the site and then the user would need to generate a unique key per application they wish to use. This would then be used to login. This is my preferred solution as each key is unique per application and user i can tell which application called the api and whether the user approved it.
My final option is to implement oAuth. We are currently waiting for the 2.0 version to be finalized and do not have the time to keep updating our code as the spec may change.
This is the first API i have had to build and i was wondering if i have understood this correctly? I'm assuming in option 1 the application could log the user credentials and use them maliciously but how does twitter overcome this issue with their third party applications? Or is it simply up to the user to trust the application they are using? If this is the case then would option 2 and/or 3 be feasible in the meantime until i switch to option 4.
I'd appreciate your feedback. Thanks
OAuth 1 and OAuth 2 are both viable options. But you will come a long way with basic authentication aswell (as long as it is over SSL). Don't be scared :)
I've implemented an API provider over OAuth 1.0. And since there are so many ready made libraries for OAuth1.0 for many platforms I would not be scared of using that either, much of the work has been done already, both for you as a provider and for third party implementors.
Anyway: you can always couple basic authentication with some very simple signing of the request using an application key and secret, say for example that as a third party developer you have to call.
https://yourapi.com/?user=11111&password=232123&random_string=23123&api_key=THIRD_PARTY_KEY×tamp=1212121212signature=efefefefefef
where the API implementor has to sign perhaps the random_string, timestamp and api_key with the secret. Then you would at least have a way of shutting down malicious apps.
I'm diving into web development and I've built a few basic rails apps, but now I'd like to begin learning how to securely connect my iOS apps with my Rails apps. For example, if I want my iOS app to query my Rails webapp for some data from the DB by passing parameters in the url...
http://mywebapp/mycontroller/search?q=keyword
...what are some common web development methods I can use to prevent anything (or anyone) other than my iOS app from successfully executing that search query?
I'm sure this type of forgery that I'm trying to prevent has a formal name, but I'm very new to web development and I'm still learning all the jargon. Thanks so much for your wisdom!
Use the trick that Rails uses in the protect_from_forgery by generating a unique key for you iphone app. Then ensure that your app passes that key in the requests to the server. You can then write a before_filter to ensure that the request possesses the key. If it does then you process the request. If it does not then you return an error with a custom message explaining why they can't have access.
You could create a hash and use it as a token which would be passed with each call to identify your application (hard coded value in the app) and the session (current ip address of the client.) So: hard_coded_value + ip_addressed -> MD5/SHA1 (whichever) = token. Your server would also have a copy of the hard coded value as well as the calling client's ip address, perform the same hashing function and compare the results. If they match, it's your app. If not, then it isn't.
you should add HTTP basic authentication in your web app (search file)
Refer these links -
http://en.wikipedia.org/wiki/Basic_access_authentication
http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic.html
Basic HTTP Authentication on iPhone
NSURLConnection and Basic HTTP Authentication in iOS
Building an iPhone OS application that will allow users to anonymously post information to a web application (in my particular case it will be a Rails based site) ... and I want to ensure that I only accept posts that originate from a specific application running on an iPhone/iTouch.
How is this best accomplished?
(btw, if your answer applies to Android please feel free to post it here as well as I'm curious to know if the techniques are the same or vary).
Thanks
The best way would be to implement a known call and response pattern. Send a value of some sort (integer, string, hash of a timestamp) to the iPhone/iTouch application. Have the application modify this information in a known way and send it back for verification. Then all you have to do is use a different modification algorithm per-platform and that will verify what type of device is being used.
VERY simple example:
Server sends 100 with the response to an iPhone.
iPhone adds 10 to this value and sends back with request.
Server detects the value was increased by 10 and now knows it was from an iPhone.
Then on your Android clients add 20 and on another platform add 30 and so on...
You could also add a hidden field in the form. or in the data being passed up if it is XML or other format
Encrypt or sign something using the public key of a key pair, then decrypt or verify it on the server with the private key. Ultimately, anything that can be sent can be duplicated, be it a spoofed html header or an encrypted block. The app has to know the secret handshake, and anyone with access to it (and sufficient technical skills) can figure out the secret handshake.
I would suggest the following approach.
Build an ssl enabled access to your rails app.
Now create a user account for every plattform you want to use and enable your applications to log in with the correct key. If you use the ssl standard in a correct way there shouldn't be a way to sniff the password and you can use standard components on the rail and the phone side of your app.
You then need to secure the login credentials on your phone with the appropriate technics. Eg. put it in the keychain on the Iphone.