x-auth-token vs x-access-token vs Authorization in JWT - authentication

I have seen different solutions when building JWT-based authentication systems between react and node. There are many examples, and many of them use different headers.
What is the difference between headers
Authorization
x-auth-token
x-access-token
and when should they be used? For example, in this answer is explanation that Authorization would be the one to be used. However, as stated in another answer here which is linking to here it states that "The Authorization header is usually, but not always, sent after the user agent first attempts to request a protected resource without credentials."
Which leads to conclusion that when making the request for some protected page behind login, one should not use Authorization header at once, only after it has first been rejected.
Thus, what is the "correct" way of doing the checks, and with which protocol?
For example, should one start with x-auth-token in header when logging in with client -> server, and to requests after that use x-access-token, and if failed then use Authorization token?
I know, typically only one of them is used, and in many cases it seems that Authorization is the correct way, adding that already in first attempt not only after the first one has failed. And I can make the application work regardless.
But out or curiosity and in sake of correct coding, what is the difference with those, is there more to use, and what is "the right way" to do the autehtication process?

I believe that this and this other answer might give you a nudge in the right direction:
Authorization is the primary header used by clients to authenticate against peers in HTTP as foreseen in RFC 7235.
[...]
Please note that with X-Auth-Token being an unregistered header, it is subject to no formal specification and its presence and content is always tied to a respective application. No general assumptions can be made on it.
And in the other answer:
The best HTTP header for your client to send an access token (JWT or any other token) is the Authorization header with the Bearer authentication scheme.
Hence, I believe that the "international convention" (if I may) appears to be to use the Authorization header, as the x-access-token is not standard and unregistered, so I'm guessing it's better for code readability to use an already known standard.
Furthermore, even the team behind JWT recommends using the Authorization: Bearer <token> scheme:
Whenever the user wants to access a protected route or resource, the user agent should send the JWT, typically in the Authorization header using the Bearer schema.
However, I understand your confusion: several tutorials around the internet seem to be using the x-access-token to send JWT tokens.
EDIT I think you might find it useful to read the relevant MDN Docs on HTTP Authentication - Authentication Schemes.

Related

CouchDB Proxy Authentication security - user roles confusion

On user auth success my auth server generates a token and passes it to the client.
The docs say that the client has to add the following headers:
X-Auth-CouchDB-UserName: username;
X-Auth-CouchDB-Roles:comma-separated (,) list of user roles;
X-Auth-CouchDB-Token: authentication token.
Does it mean that the client defines his own roles on every request? Why can't he add 'admin' into the list of roles then?
A client is anything that uses or requests resources from a server.
"The client" in this case is your proxy/auth server, not a web browser. (The documentation could probably stand to be clarified a bit.)
So yes, your proxy/auth server, the client to CouchDB, should set that header as appropriate.
By extension, it should also not pass through any X-Auth-Couch headers received from its client (presumably a web browser).
Good observation. Using the JWT Authentication would seem to close this loophole as my understanding is the entire token is signed-over.
That said, in neither case can one avoid:
having to fully trust the entity holding the secret
having to carefully guard against leakage of its headers
The former is sort of unavoidable, as the point of these plugins is to delegate authentication. Either you trust the proxy (or JWT issuer) or you leave those authentication_handlers disabled.
The latter is something that e.g. OAuth 1 hardened itself somewhat against, in that ± the entire request was signed over and one couldn't simply take a couple auth headers from an earlier leaked request and slap them on a new forged request. Nonce and timestamp fields were supposed to be checked to avoid verbatim replays of prior requests as well. (All this was dropped in OAuth 2 for whatever that's worth… and even OAuth 1 had some notable loopholes in practice…)
So in practice either the Proxy or the JWT authentication handlers should be used with care. Assuming a "firewall" of sorts drawn around both your CouchDB and authentication source, then as #Flimzy's answer mentions preventing unexpected headers making their way inwards from outside that boundary — as well as keeping the real headers from leaking outwards — should mitigate most potential abuse.

Should we check token in case of Authorization Code flow?

It's a know problem that Instant Flow struggles from confused problem, so you have to check whether access_token you received was given to your application.
I always considered it's not a problem for Authorization Code flow but in this answer it was mentioned it is not so and you have to verify token even in Authorization Token flow.
But honestly I can't figure out a workflow where it's necessary. Like we receive a code and then make direct request for a token (specifying client_secret). I don't understand how we could be forced to use a wrong token in this flow.
The answer that you refer to talks about an access_token delivered to a Resource Server. That is also in general where the "confused deputy" issue applies.
In your post you refer to the Authorization Code delivered to the Client. That is different and does not suffer from the same confused deputy attack as described.
It should be noted though that the Authorization Code grant type may be vulnerable to a related attack ("Authorization Server Mixup") if the Client talks to multiple Authorization Servers (AS) somewhat for the same reason: the Client is not able to detect if the Authorization Code is actually issued by the AS that it thinks it talks to. Registering a Redirect URI that is specific for each AS addresses this.

Where should the access token be placed at successful login?

I'm planning an API and I haven't found any information about where the access token should be placed in the response. I'm interested in the case where I'm providing the access token. What is the best practice to send the token to the clients (from the backend service)?
Should it be sent to clients in the Header or in the Body of the answer?
You should look at examples and see what others do. For example, Facebook, Twitter, Google, Amazon... and all those popular PaaS services exposing a REST API all use OAuth2 as authentication mechanism:
In OAuth2 you'll see the specification requires to send the generated token to the client in the body of a json response: https://www.rfc-editor.org/rfc/rfc6749#section-5 . But you can also see how Google and other vendors extend this mechanism so it can be sent as a callback url param, for example (Check out https://developers.google.com/identity/protocols/OAuth2UserAgent).
Once you get the authorization token you put it on the Authorization: HTTP header you send on your requests for accessing protected resources. They have to support this way of doing it, because it is how the OAuth2 standard specifies it https://www.rfc-editor.org/rfc/rfc6749#section-7
If you want to tinker a little bit more with oauth, check out https://developers.google.com/oauthplayground
(OAuth is pretty much the same thing.)
They usually also extend the Authorization header mechanism to allow the token to be provided as a GET/POST parameter in the url or the body of the response, respectively (For example, Facebook's Graph API also supports passing an access_token= parameter on your HTTP POST request body or GET URI). There is no way to manipulate or even read HTTP headers on a javascript browser application (see the modern fetch API and other proposals on Accessing the web page's HTTP Headers in JavaScript), so providing this functionality makes life easier for many app developers.
Another popular authentication scheme is SOAP authentication. It doesn't support tokens but it supports digest authentication, which is a similar thing. The interesting part of it is that it is not HTTP/Web based (although it is primarily used that way), so you can use it over other application protocols. It's a little more cumbersome, but you can find ready to use implementations for both server and client.
You can also use digest authentication over HTTP without SOAP. It is also based on Authorization: headers and every browser supports it. Check out https://en.wikipedia.org/wiki/Digest_access_authentication to see how the authorization headers are formed in different ways depending on the level of security you want to reach.
Some services, like redmine, allow you to use an API token (API key) instead of a session token. Then you can make basic http auth on your requests like https://whatever:yourapikey#example.com/protectedMethod, although passing of auth data on URLs is currently deprecated in favor of basic auth header, and plain passwords / static API keys should only be sent over secured SSL connections. In this case the client can have the server generate an api key using a web interface or a rest api (so the generated key will be passed as a JSON response). This method may not be such a good idea, though: Check http://talks.codegram.com/http-authentication-methods#/intro if you want to know why, and also this question discussing where to put them: Where should I place API keys in REST API calls?

REST GET requests, verbs and apikey

I want to create a flexible API Rest server. I will allow the clients to authenticate using HTTP or an APIKEY.
My question is: what is the correct way to add the apikey to a GET request? My problem is the apikey pollutes the url.
I imagine something like this : /book/1/apikey/s4cr4t !
In my opinion you should only use the Authorization header. That's what it is there for.
Putting it in the URL is a bad idea because:
a) as you said it pollutes the URL
b) if you decide to go SSL for security then the API will still appear in log files
c) caches will end up creating multiple copies of the same representation, one for each api key.
For more information on creating your own Authorization scheme go here.
Credentials may be passed using the Authorization header:
GET http://domain.com:/book/1
Authorization: apikey="s4cr4t"
It all depends on how far you want to go but the mechanics stays the same:
Context
The goal is to identify the client with some level of security. (Note: Security is another detailed discussion). Remember that one if the “features” of REST is to be stateless: That means no session state on the server except for resources. To keep the client stateless, it needs to supply on each request enough information that the request is independent. It must give the server a way to identify the client such as a username/password, API Key or token.
You have various options to do this so here are some:
Add HTTP headers to identify the client
Here one can use the Authorization header and send it with each request. There are various authentication schemes but stick to the standard ones such as Basic Auth. Here you would probably stick to SSL. The authentication process generates a kind of token if you like.
You can also make use of a cookie. The cookie must contain no information except that it is a “pointer or key” to a stateful session resource on your server (note: session it a resource which is “rest-legal”). You can create this resource by doing a PUT (+info) with response 200 OK or POST (+info) with a response of 201 Created and Location: /sessions/123334. The session can then be validated by the server such as timeout, valid client ip address, api key etc.
With the method above, you can also define a customer header such as Api-Key: XXXX. But then you limit yourself to special client. Set-Cookie are “well known” headers so browser will handle them kind of transparently. The authentication process can then be done by following links and filling in forms (PUT + POST) to authenticate (create session resource).
Encode an identifier in the content
Here you are free to do what you want too. Just add a field/token/id to your content and let the server verify it.
A RESTful API does application flow by resolving links. See also HATEOAS and Fielding's words. This also applies when you have a separate process of logging in to the application.
Do not encode any data in the URIs. (Out of band information)

API Design: HTTP Basic Authentication vs API Token

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.