I have a JSON REST API written in Symfony 2.7, and I want to authenticate & authorize users. This is my first time doing this, so I have some doubts/questions.
For that, I thought several methods:
User & password, and then save a session in the back end
Same as 1), but add an "apiToken" (randomly generate when user register) and then sending back & forth the apiToken in every single request to check user identity.
Use OAuth (which I'm currently reading about it).
I read that using OAuth for a simple API is like an "overkill", but on the safe side it sticks to standards and also allows me to use it when using my API with mobile devices and different platforms.
Also, I don't know too much about security flaws of using method 1) or 2).
I know this is maybe based on opinions, but I don't know any other site to post this question, as Symfony official mailing was shut down and migrate here it seems.
As you seems to know, your question is too opinion based.
If I can give you some advices (too long for a 600chars comment),
OAuth is powerful, but so much free.
I mean that you can easily implement it sort as everything works well while having a set of potential security issues without being aware of their existence.
Libraries and bundles providing OAuth are hard to maintain because of the new security issues regularly found.
On the other hand, if you need the benefits of OAuth (be a client and/or a server, compatible with the most part of social networks), go learn OAuth and do your experience with it.
Otherwise, use a simple credentials/request token two-step authentication.
See the JWT Authentication tutorial by KnpLabs,
Symfony Guard Authentication by Ryan Weaver,
and the great LexikJWTAuthenticationBundle, easy to implement and to use.
Related
I'm practicing my Symfony 2 skills and would like to set up a simple REST API for a tiny application of mine.
I've set up REST Api with FOSRestBundle in few minutes. Perfectly. After setting it up, I've decided to secure it with OAuth. I've decided to go with FOSOAuthServerBundle. The stuff is working perfectly.
I've readed tons of materials and I'm wondering if I understand all of the stuff correctly. I understand how OAuth works, I'm just not sure if it was a good choice for my problem.
In fact, there will be many consumers available: users will be able to create their own apps based on the data fetched from API, there might be CMS plugin.
I suppose I misunderstood OAuth protocol in few ways: does OAuth always require end user action (giving a client app a permission)? Does users always have to re-authorize an app after access_token has expired?
Let's say an user want to fetch his content within my API - just to fetch some non-sensitive data. Does it require authorizing an app by the end user? I think I'm a bit lost here.
To avoid questions, yes I've read this few times and reading it all the time ;) I just think it's better to ask instead of copying terrible solutions, practices and false knowledge.
Hi I was looking at flask-login at handles the session login nicely, this work good for templating and views where I have access to the session.
Nevertheless I have been trying to know if there is a way I can send a user_token to authorized a call. I looked at the documentstion and is very vague regarding this. It said that I should
Implement get_auth_token in my User object.
Decorte a #user_loader function that can load the user token base.
I have though seen the following (please correct me If I am wrong)
Cookie base to store the auth token is there a way I can decide to send the token as part of the parameters, body or in the headers insteado having to get it from the cookie.
I am not quite sure how to authenticate a call with auth token.
I got a Way better approach that fits better my needs. Basically I extends LoginManager pretty easy and straighfoward if you take a look at the source of flask-plugin you come to realize that there is a call that is made #before_request there is a method called reload_user, this is the what I end up doing
class CustomLoginManager(LoginManager):
def reload_user(self):
if request.headers.has_key('Authorization'):
ctx = _request_ctx_stack.top
ctx.user = User.get(token=request.headers['Authorization'])
return
super(CustomLoginManager,self).reload_user()
If in my header I pass an authorization key then I will try to load using this key instead of session based approach, of course I am going to need to add more security layer to this approach proably by signing the key but overall this was what I needed.
Thanks all.
BTW you can override a bunch of others method and I highly recomend to take a look at the plugin source, so you can understand more deeply what it does 644 lines of codes worth reading
https://github.com/maxcountryman/flask-login/blob/master/flask_login.py
It seems like you're wanting something like OAuth instead of using Flask-Login. In case you don't know (quoted from Wikipedia), OAuth is a protocol that utilizes tokens in order to access resources on behalf of a resource owner. Think giving a user the ability to give out a valet key to certain portions of your site. Many sites, such as Google, Facebook, and Twitter use OAuth for authenticating third party clients in order to access certain user resources.
Right now, there's a split between the less flexible and less complex OAuth 1.0a and the more flexible but more complex OAuth 2.0. Many libraries exist for OAuth 1.0a in Python, but fewer for OAuth 2.0. However, there is a selection of those for OAuth 2.0 if stability isn't a top concern right now.
For the client, Flask-OAuth is available if you're going with OAuth 1.0a, and it is maintained by Armin, the Flask creator itself, so you can feel assured that it won't die. For the provider, there's an extension called Flask-OAuthProvider with OAuth 1.0a support. If you don't mind integrating it yourself and want 2.0 support, pyoauth2 provides you with both a client and a provider, though it looks less maintained.
Hopefully this helps you with exploring one possible avenue to utilize auth tokens, albeit without using Flask-Login. In my opinion, one shouldn't re-implement a protocol unless they understand it, so I recommend reading up about OAuth even if you decide not to use it. Many great articles exist on it, such as this article from Google and this one, too.
Just as an update, Flask-Login now has a 'header_loader' function, which can be used in conjunction with the standard 'user_loader'. Taken directly from the docs:
#login_manager.header_loader
def load_user_from_header(header_val):
if header_val.startswith('Basic '):
header_val = header_val.replace('Basic ', '', 1)
try:
header_val = base64.b64decode(header_val)
except TypeError:
pass
return User.query.filter_by(api_key=header_val).first()
Here's the link to the section in the Flask-Login docs
Not sure if the title of the question expresses good my problem, so I'm going to do my best to explain it here:
I'm writing a RESTful api using php and Restler. Now here comes the problem:
There are some services that I'd like to protect, that is, know if the user requesting that service has enough privileges.
All the services that I'm implementing have to be consumed using javascript, so the traditional method user/password won't work beacause everyone will see that!
I'd also like to limit the amount of requests an anonymous user can do, like twitter does with the search service.
What can I do to expose my api to everyone, but only let users with priveleges complete their requests?
I stumble with this post: REST authentication and exposing the API key but at the end, no solution was provided.
I'm very open to any alternative: like OAuth. I would like to use something that integrates well with restler though, but if that is not the possible, then its ok.
I've seen a lot of info, saying that an api key would do the work, but since I'm using javascript, how can I protect those keys from being used by other users?
Update: Restler 3 is released with hybrid access support using #access hybrid comment and is available here!
Just in time with the right question :)
Your question has two parts
1. How do I do hybrid access (both public and protected access) with Restler
Restler 2 does not support hybrid access, but Restler 3, which will be released in August 2012 (this week) will support hybrid access, exactly built for your use case
You can follow the development at twitter and/or facebook
2. How can I protect my API when the primary consumer is JavaScript
For simplicity you may use HTTPS with Basic Authentication or HTTP with Digest Authentication
Another alternative is described in this article. It is not written specifically for Restler but it is easy to adapt to Restler. Let us know if you need help on that
Background: I am trying to create an SMS API service. The developers have a Dev ID, and an API secret key assigned to their developer account. The developers will be creating apps which will issue calls to my API. But the application issuing the call must be verified first.
Issue: The main issue i have is with authentication. I read up on OAuth and pretty much uderstood it. I read through this presentation (Slide 71-82). All OAuth articles talk about the OAuth 'dance' or the 'love triangle'. My problem seems to be, that i dont see a proper triangle in my case. Or, a better way to put it would be, the triangle doesn't seem to be complete.
What i mean by that is, in the case of lets say, LinkedIn, trying to make some app which helps users associate their LinkedIn acc with twitter, OAuth makes complete sense. Because LinkedIn needs to get resources from twitter ON THE USERS BEHALF (Cuz the user HAS A TWITTER ACCOUNT). In my case, only the consumer has a developer account registered with my service. The end-user doesn't have any credentials for the consumer to ask on behalf of. So how can i implement Oauth? So what will the consumer ask the provider? Will it only state that "watch out, here i come?". Cuz that seems pretty pointless unless its asking for a request token in exchange for an access token. But in this case since the end user doesnt even have an account, the steps seem useless.
So, i cant figure out how to go about this authentication issue. Ive tried thinking about using php sessions so it can help me associate a token with the particular client who is using the API. But the REST/OAUTH purists seem to disagree on the usage of sessions in authentication. They claim that OAuth is a standard which has proven itself and that is what I should use instead of coming up with my own obscure schemes.
From your description it seem that you're in a two party scenario only (developers write code which accesses your API on their own behalf, not on behalf of an end-user), so that means indeed that doing the full 3-legged oAuth scenario isn't needed.
You could use pretty much any authentication scheme and that would work (API Keys, other oAuth grant types [see below] or even ID/Secret combinations. In the oAuth world:
Look at the other oAuth 2.0 Grant types: especially resource owner PW grants - https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-26#section-4.3. It's slightly better than username-password because the PW isn't passed across the channel all the time (it passes once though) and it assumes the developer writing the code is the owner of the credentials.
Look at oAuth v1.0: this different in various ways to v2.0 but one feature it does have which some people like is the way tokens are used - which is rather than being passed across the wire they are used to generate a hash in the client and then the hash is verified on the server side. It's more expensive and complex than checking a key but it's less prone to attack.
In the non-oAuth world, if it's primarily a server resource used by developers directly, an ID/Secret or API-Key pattern is probably more than sufficient and it's much easier to implement for your developers.
Re: oAuth - if you're doing any type of user auth then definitely stick with the standard - the stuff is complex and having libraries out there really helps. If it's developer-api you likely don't need to go that far.
If you want the API to be secure in an ideal world anything which requires the security token to pass across the gaps should be secured using SSL, especially if that client code could be running on a mobile device or laptop which might communicate over wireless. If this isn't the case, someone could jump in an copy a token from one of the devs.
The only one of the protocols above that avoids this is the oAuth 1.0 variation since the secret never leaves the client but is used to hash instead. But it's complex. Last one to look at is the Amazon AWS pattern which does hashing similar to oAuth 1.0 http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html and people emulate quite a bit.
I am building an ASP.NET MVC 3 app that has both a www front-end (www.example.com) and a developer API (api.example.com). I'd like to make a simple service available to developers where they sign up for a key and make REST calls with it. I'm unclear on a few things:
1) How should I generate and store keys? Is it acceptable to store them in plain text in the database or should I hash and salt them?
2) How do I authorize API calls? I'm guessing I don't want to do this via ASP.NET Membership for this.
Things like rate-limiting seems straight-forward once I understand those two issues.
1) That's really up to you. I've seen it done completely differently in different API's I've worked with. Some keys closely resemble GUID's, others are clearly just random strings, but the important thing is that they're unique and not easily guessable. As far as how you store it in the database, how much effort you put into protecting your data really depends on the level of sensitivity of users' accounts. If the nature of the service you're providing is highly confidential and/or you may end up being audited, then you should take whatever means are necessary to protect the data (using a 1-way hash and salting). My personal philosophy is to keep things as simple as possible until there's a reason to introduce added complexity, but I've worked on sites that used 1-way hashing with salts for authentication.
2) That depends on who's going to be using your service. You could use the built-in ASP.NET Forms Authentication Membership Provider, and even integrate it with your public website, but that will limit the usage of your API to developers using a platform that supports cookies on HttpProxies, and will make your API harder to follow. Most REST-ful services I've had experience with have used a combination of basic authentication and SSL, which will provide the broadest range of developer support, but will be more complicated to implement on your side. On the server side you'll have to capture the user credentials out of the HTTP headers and authenticate them against your user database.