API Design: HTTP Basic Authentication vs API Token - api

I'm currently creating an authentication system on front of a public web API for a web application. Given that each user account has an API key and each request must be authenticated, I have two alternatives:
Using an HTTP Basic Authentication, like GitHub does.
Requests must be sent to the URL
http://api.example.com/resource/id
with basic authentication
username: token
password: the api key
Passing the API Token as querystring parameter.
Requests must be sent to the URL
http://api.example.com/resource/id?token=api_key
There's also a third option which is passing the token within the URI, but I honestly don't like that solution.
Which solution would you adopt and why?

Best bet might be using an API key in the header (e.g. 'Authorization: Token MY_API_KEY') instead of as a url param:
Advantages over HTTP Basic Auth:
More convenient, as you can easily expire or regenerate tokens without affecting the user's account password.
If compromised, vulnerability limited to API, not the user's master account
You can have multiple keys per account (e.g. users can have "test" and "production" keys side by side.)
Advantages over API key in URL:
Provides extra measure of security by preventing users from inadvertently sharing URLs with their credentials embedded in them. (Also, URL can wind up in things like server logs)

Many times I had to think about how to authenticate users/requests onto APIs and after comparing more solutions I ended up with using the Amazon's solution where I don't need or I can't use OAuth. This solution is based on signatures that prevents from "man in the middle" problems as Basic Auth and passing a simple token are sending plain text data. Yes you can add ssl but this will add complexity to the system...

I think that HTTP Basic Auth should be OK but just for really simple needs.
The complete (and final) solution IMHO is to implement an OAuth provider.
It's not complex, it's a simple protocol and gives you lots of flexibility.
In addition it seems to be the current trend as many big players implement it and it's supported from many many libraries.

I would prefer using the token solution. If you don't have actual users with their own username and password, then it feels like you are using the Basic Auth construct not as intended. Not that that's necessarily wrong, but not as clean, IMO. It also removes the need to use custom headers and I think it makes implementation on both sides easier and cleaner. The next question I would be asking is if you should be using two-factor authentication or if you need to manage sessions at all.

Related

How to secure a web API with public key from unauthorized access?

While understanding the nature of web API, Some questions regarding its safety were raised. What are the best practices to design web API such that only authorized user should be able to access it. I tried to check below options, but none was able to achieve perfect safety.
1) I cannot rely on request origin, referrer or user agent string since they can be easily spoofed.
2) Web API requires just a public key to access it so CSRF token is also not suitable to implement.
Is there any other way I can ensure request is coming from trusted source only?
My use case is I would like to implement client side API like google map, where any one who has purchased an access to API, will whitelist their website domain and can include my plugin on their website. Plugin will then make request to my API on behalf of user.
Is it a good idea, if I apply some request signature logic on web API so my server can validate the requester and reject the unauthorized origins. I assume I would have to keep my request signature logic secret and so I may need some obfuscation on code.
You do not mention anything about the usecase, especially if the client is a system or a person?
First off, security by obscurity is never a good choice. Second, it is considered bad practice to "create your own security system", it is much better to stand on the shoulders of others who has the knowledge and experience in security.
Without knowing the exact usercase, it is hard to come with a lot of suggestions... however, i'd suggest you look at at stuff like jwt tokens(i'm guessing that you have a person behind a webclient as the user of your webservice)... since you've tagged the question with asp.net-web-api i'd also suggest you have a look at https://identityserver.io project ... I've previously used IdentityServer4 with success in a large asp.net webapi project...

Web API security using tokens

I have built a Web API and now I am trying to determine the best approach to secure it.
I would like to use tokens along with credentials and thus, once the user is validated, on future requests a token can be passed with the http request. This API will always be called by one particular account and the username/password will always remain the same.
I am working with an already existing site backend, which has its own login implemented and stores user data. So I would like to stay away from creating new database tables to store user records. For that reason, I think implementing .Net Identity is maybe a overkill.
One of the options I am thinking of is grabbing the credentials from the http request and attempting the SQL connection with it. If the connection passes, then the user is legit. If it does not, it means I have to return access denied. Is this a good way of going about it? If yes, what can I use for token generation and validation?
Check out this guide which is specific for Oauth tokens with .NET:
OAuth with JSON Web Tokens In .NET
Also, make sure to follow the guideliness, because tokens must expire and be renewed after a while, for security reasons. You shoudn't use a permanent token, of course.

What's the benefit of OAuth for securing REST APIs?

I want to make a web application that's a Single-Page client that interacts with a REST API in the server. I need to authenticate users of my app as opposed to authenticate third party-apps (the latter being the focus of most tradional REST bibliography).
After googling a lot, I found there are many options (Basic HTTP Auth, HTTP digest, OAuth, etc) and several desirable properties one might get depending on the one chosen. For example, Basic Auth is simple but sends plain passwords unencrypted, which is not a good idea unless you guarantee that your app will run under TLS. Digest on the contrary doesn't send the credentials on every request, but prevents strong password encryption and is vulnerable to man in the middle attacks[1]. Meteor introduced SRP which avoids storing and sending passwords[2].
It appears to me that the consensus is to use OAuth, particulary the OAuth2 credentials flow, since I want to authorize access to my resources on my own server[3][4][5]. What I don't get is what are the benefits of this particular approach. I do get the benefits of using OAuth as a form of delegate authentication, much like those of using OpenID for federated authentication: you don't handle authentication data at all in your server. But in the case you apply the credentials flow for authorization (or OAuth1 2-legged flow for that matter), not introducing a third party, it looks like you still have to handle authentication by some other means, like HTTP basic or digest. So if you're doing that why not stick to that only method, and send the credentials on every request, instead of the token?
It's just to reduce the amount of requests where you have to actually send the credentials? It's just to stick to the OAuth convention? Those don't sound like strong arguments over the other methods. So, I'm I missing some other aspects or did I misunderstood something?
If you are not federating, there is not really a good case for using OAuth.
If you just want to authenticate to your own service, basic or forms authentication is the way to go. The catch, as you've pointed out, is that you must use HTTPS. However, that applies to all authentication methods.
As long as you're using HTTPS, you can leave protection of credentials while in transit to the transport level security. That's what it's there for and (for the most part) that's what it's good at. If you're using plain HTTP (anywhere in your application, not just for authentication), you're done. There are all manner of very clever MitM attacks that totally break the security of any system that employs HTTP anywhere (Moxie Marlinspike gave an interesting presentation on the subject at Black Hat back in 2009).

Authentication security concerns

I am a beginner web-developer and I have some doubts about the security of an API that I developed. It's a simple web-service that requires authentication in order to access/modify data.
I am wondering what are the best practices for authenticating users via HTTP.
Currently my app works like this:
User authenticates through an API request (POST) which requires the username and the password. The response contains info about the user and a TOKEN which will be used in the future for further requests.
My concerns: I don't know if the auth request should be POST. It sounds more like a GET, because POST should create something (at least this is the convention in Ruby on Rails). And then, even with POST or GET, the information is still "visible" during the transfer of the information. I heard something about HTTPS - how does that solves the problem?
The token is generated at user creation time - and remains the same in time. Is this bad? Should the token be generated again after a "logout"? I've seen APIs that use an API_KEY along a token for authentication. How does that work?
I have some GET requests to retrieve information about something. With this request I pass as an parameter the token retrieved from the authentication request. Is this ok? I mean that token is sensitive information.
Where can I find more information about these concerns of mine (book, article, w/e)?
HTTPs encrypts all traffic to your web site, and so would hide any get and post requests. It requires you to purchase an HTTPS certificate (which are cheap), and get a non-shared IP to host on (not so cheap). (If anyone talks about self signed certificates - well, it's possible, but ill advised if external people want to talk to your service).
Having a long lasting login token can be bad, it depends what sort of non-repudiation you want. If someone can log in 2 years ago, and continue using a token how do you know it's still the original requestor? Tokens should expire and have a way to re-request.
API keys generally work on a shared secret which is swapped out of band (by getting it from the hoster's web site generally). A custom authentication scheme and header is used, and must be calculated and checked for each request. This doesn't require HTTPS - the shared secret is used to generate the authentication header, but isn't sent with it, so the secret doesn't travel with each request. Of course you need to write this code, and figure out what you want the process to be. I'd generally avoid this unless you know what you're doing - you need to take a canonical representation of the request, sign it, then use that as the header. It's not complicated, but it's not simple either.
The problem with GET is more one of physical security than web security - I know that I log into sites regularly at work or at home in the company of others - I certainly don't want my credentials appended to the URL as a query string.
Using HTTPS (SSL) will secure your postdata as the information is encrypted before it is sent over the line. The encryption algortihm uses some quite clever maths in generating its decryption tokens to ensure that it's not susceptible to a man-in-the-middle attack.

How to use OpenID in RESTful API?

I'm building Pylons-based web application with RESTful API, which currently lacks any authentication. So I'm going to implement that and in order to avoid all the trouble and caution with storing user passwords, I'd like to use OpenID for authentication. What would be the best way to do this? Are these two things compatible? Are there existing REST APIs that use OpenID that I can take inspiration from?
I've now spent some time researching the options and would like to summarize the findings.
First, a little bit more context -- I develop and control both the service and API consumer. Consumer is Flash-based app that is served from the same host the API is now and is supposed to be used in browser. No third party clients in sight yet.
So the question can be divided in two parts,
how do I do the OpenID authentication via API
how do I maintain the "authenticated" state in subsequent requests
For first part, OpenID authentication almost always includes interactive steps. During the authentication process there will most likely be a step where user is in OpenID provider's web page, signing in and pressing some "I agree" button. So API cannot and shouldn't handle this transparently (no "tell me your OpenID provider and password and I'll do the rest"). Best it can do is pass forth and back HTTP links that client has to open and follow instructions.
Maintaining "authenticated" state
REST APIs should be stateless, each request should include all the information needed to handle it, right? It wouldn't make any sense to authenticate against OpenID provider for each request, so some kind of session is neccessary. Some of the options for communicating session key (or "access token" or username/password) are:
HTTPS + BASIC authentication ("Authorization: Basic ..." header in each request)
Signing requests Amazon-style ("Authorization: AWS ... " header in each request)
OAuth: acquire Access Token, include that and a bunch of other parameters in each request
Cookie that stores session key ("Cookie: ... " header in each request)
Signed cookie that stores session information in the cookie itself
There's just one API consumer right now, so I chose to go for simplest thing that could possibly work -- cookies. They are super-easy to use in Pylons, with help of Beaker. They also "just work" in the Flash app -- since it runs inside browser, browser will include relevant cookies in the requests that Flash app makes -- the app doesn't need to be changed at all with respect to that. Here's one StackOverflow question that also advocates using cookies: RESTful authentication for web applications
Beaker also has nice feature of cookie-only sessions where all session data is contained in the cookie itself. I guess this is about as stateless as it gets. There is no session store on server. Cookies are signed and optionally encrypted to avoid tampering with them in client side. The drawback is that cookie gets a bit bigger, since it now needs to store more than just session key. By removing some stuff I didn't really need in the session (leftovers from OpenID authentication) I got the cookie size down to about 200 bytes.
OAuth is a better fit for API usage. Here's an example of OAuth in use in Python: oauth-python-twitter. Leah Culver's python-oauth library is the canonical implementation of OAuth in Python, but python-oauth2 is a recent contender that is getting some buzz. As for inspiration, django-piston has support for using OAuth to do auth when creating RESTful APIs for Django, though the documentation isn't as nice as I'd like for that particular topic.
If you build API, you could check OAuth protocol. It's complementary to OpenID.