I know there is enough content for this question on the Stack Overflow but my subject is not the same as the others. ( Kinda the same but not equal )
I want to hear the community thoughts of what I doing and to see if I can improve somewhere or not.
I'm currently using BASIC Authorization for my login EndPoint as it doesn't require complexity and its over https so its fine the way it is.
Example:
GET - /api/login
Authorization : Basic BASE64String(username:password)
Some of my EndPoints require Tokens to be granted access to the resource. These Tokens I'm sending trough Headers and Https-Secured.
The thing is I'm not using a conventional method of doing these Authorizations. Some examples below:
Example 1:
GET - /api/hardware/{PUBLIC_TOKEN}/getMe
Authorization-Hardware : PRIVATE_TOKEN
This EndPoint doesn't require the Authorization-Hardware Header, but if included more things are done by the API. ( Not relevant here )
Example 2:
GET - /api/login/{id}
Authorization-Person : USER_TOKEN
This EndPoint otherwise is necessary including the Authorization-Person Header with the User Token to access the resource. ( Note that how the Token is generated is irrelevant here )
To access the API EndPoints an HTTPS request is necessary.
I gave arbitrary names to the Custom Headers and EndPoints above just to give a picture of what my Authorization Schema is, the names doesn't match the original ones. So don't bother the names just foccus on the schema.
My question is: Not following the convetional way is such a bad thing ? Creating Custom Authorization Headers is bad somehow ( if it is why ? ).
I find this way simpler to give Authorization and a secure way of passing tokens, all these Tokens can be re-generated in the platform again.
Lots of devices and a Mobile Application is already using this Schema, but its all under Development Environment and its not in Production yet. My fear is that this non-conventional way of doing this can affect users of the API in the future. Hope the community thoughts can help me to improve this.
EDIT: 26/03/2017
I would like to know if it would be better and why implementing in the way that is described in the protocol, as its harder to fetch from the Headers when multiple Authorizations is required than when you have a Custom Header and wants to retrieve its value.
Following the Protocol you should use Authorization Header like this:
Authorization: <type> <value>
Example:
GET - /api/login/{id}
Authorization : User USER_TOKEN
But I just can't see what I gain following this, because when fetching its value would come a String or in the example case it would return User Token.
Using an Custom Header its way easier validating the Token. Multiple Authorizations can give a headache too following the protocol way.
TL;DR Some header names such as Authorization have special rules about caching as well as proxy & client handling; your custom header names would not get the special behavior unless you modified every single proxy & client.
The point of using the common Authorization: <type> <value> header as defined in RFC7234 is mostly to ensure that clients & HTTP proxies that natively implement handling of those headers behave CORRECTLY.
Section 4.2 of RFC7234 says:
A proxy forwarding a request MUST NOT modify any Authorization fields
in that request. See Section 3.2 of [RFC7234] for details of and
requirements pertaining to handling of the Authorization field by
HTTP caches.
The Proxy may modify, omit, log or cache your other Authorization-* headers.
RFC7234, section 3.2 says that requests/responses Authorization header MUST not be cached (except in specific circumstances).
RFC7235, section 5.1.2, point 7 furthermore has this say to about NEW authentication schemes that use headers other than Authorization:
Therefore, new authentication schemes that choose not to carry credentials in the Authorization header field (e.g., using a newly defined header field) will need to explicitly disallow caching, by mandating the use of either Cache-Control request directives (e.g., "no-store", Section 5.2.1.5 of [RFC7234]) or response directives (e.g., "private").
So what should you do...? If you controller both ends of the system entirely, it's not unreasonable to define a new type value that might have multiple parameters to cover any combination of one or more token types, just avoiding the , character:
Authorization: MyAuth User=USER_TOKEN/Hardware=HWTOKEN/Person=PERSONTOKEN/Basic=...
The alternative depends on server & client implementations more, and would be using a , as the alternate version list form of multiple headers:
Authorization: User USER_TOKEN, Hardware=HWTOKEN, Person=PERSONTOKEN, Basic=...
Which depending on the server & client, may be treated the same as:
Authorization: User USER_TOKEN
Authorization: Hardware HWTOKEN
Authorization: Person PERSONTOKEN
Authorization: Basic ...
The problem here is "MAY" (lots of added emphasis) be treated the same. There's discussions suggestion that various versions of Apache & NGINX don't treat this consistently, and that the older HTTP RFCs are very unclear about the intended behavior.
Related
This is a theoretical question. For some APIs, user need to authenticate themselves and we have authentication token for a user. I feel using GET api is not good idea due to this token.
/get_data/?user_token=hshhlj8979kjhk&dataid=87979
Indeed it's not a good idea, but not due to GET in itself. The real problem is the token as part of the URL and the security problems it creates.
The URL portion of a request is very often cached and logged for auditing or debugging purposes, and having the token there causes it to leak unintentionally.
For example, browsers save your browsing history, and the main portion they record is the URL, so there goes your password to your history, a place it doesn't belongs and is easily exposed accidentally.
Most web servers by default also log the URLs they receive, so again there goes your token. It's quite common for it to end up in logs on web servers, load balancers, intermediate routers and so on, again leaking all over the place.
The solution to this is to strip the token from the URL portion, leaving there only data that's not security-critical. The most common place to put it is in the request's headers. Those are well respected by the HTTP standard and almost never logged or accidentally dumped like the URL.
Of course, all other methods suffer the same. POST, PUT, DELETE, OPTIONS for example, none of them should be ever called with secret data in the URL. Headers provide a "safer" place for that available across all methods. The request body is another common place, but you can't have one in GET, making a header the best alternative.
Which is the right approach to send user credentials from the front end to the backend server?
I see examples where some developers use the authorization headers and some pass the credentials in the POST body.
Credentials usually go to the request body once, when trying log in.
You should receive a token in return, although whether you send this token via HTTP header, request body or as a GET param is up to you ( or the protocol you are implementing ).
It's generally a good practice to use the header, because GET requests shouldn't include request body and passing the token as a GET parameter may not always be an option ( e.g. due to the token appearing in various logs ).
Either way, I would advise you to avoid trying to implement your own protocol and use an existing standard instead.
The only safe method for a website to transfer a password to the server is using HTTPS/SSL. If the connection itself is not encrypted, a ManInTheMiddle can modify or strip away any JavaScript sent to the client. So you cannot rely on client-side hashing.
Moreover always use headers for sending sensitive data like USER-ID, API-KEY, AUTH-TOKENS
You can refer to this stack question also link for more information and this link
I found a doubt when I was designing API. Some documents guide developers how to make and deal with token.
If I will access a website requiring token authentication, I should set my token in HTTP header, let service ascertain my validity.
Although I think designing setting up method can be flexible, for examples, setting in header or body, I don't know what difference are they?
In this token case, because token is secret info, is setting in header safer than in body? or setting in header can't make HTTP be a burden? What information does it fit with setting in header?
It's no special when data sets in header or body.
Except you have specail data needs to set in header, and then your web application only accepts the specify method to do. It follows you how to desgin the processing workflow.
The title is a bit obscure. I'm interested about some feedbacks on a specific architecture pattern.
Let's take as an example the Stripe API: when you are using this API, the system is basically broken into two parts: live mode and test mode. If you hit the "/customers" end-point, you can either retrieve test mode customers or live mode customers, based on the type of API key used.
I'm asking myself how I could implement such a pattern using an OAuth 2 access token.
In my workflow, I have a single application page (JavaScript) that communicates through my API. I have a "live"/"test" switch, so basically my whole website is replicated into two distinct environments.
When I log in into my application, my authorization server creates a unique access token (OAuth 2 Bearer token), that is send for each requests. But obviously, my access token is tied to the "session", not an "environment" (live or false), so if I want to implement a switch live mode / test mode, I cannot rely on the token, because the token is "generic".
I've thought about two options:
Depending on live mode or test mode, I send an additional header to all my request (like X-Livemode which is either true or false). Then, in my back-end, I reuse this header to automatically adds a filter on all my requests.
If I switch to live mode or test mode, I ask my authorization server another access token. This would means that access token would have additional context information. However this seems a bit complicated, and I'm not sure that OAuth 2 spec allows token to have such additional information.
I'm not sure if this post is clear or not :p.
The second part of the question, is what is the best way to implement such a system where all the resources are basically duplicated between live / test mode ?
In my understand, it should be as simple as adding a "isLivemode" property to all resources, and make sure that all my SQL queries are aware of this. Is this correct?
Thanks!
A much simpler solution I've used in the past (albeit a bit of a workaround) is just to append "live" or "test" (base64 or hex encoded) to the api key, like so:
Imagine your actual key is:
9a0554259914a86fb9e7eb014e4e5d52
In your key presentation, present your key to the user as:
9a0554259914a86fb9e7eb014e4e5d526c697665
Then use a regular expression to strip off the known characters.
Alternatively, if you're equipped to handle key-value maps, a more "OAuth2-spec" approach would be to generate unique keys for live and test and do a key-value map lookup on the request to determine if one belongs to live or test.
as part of a server REST API design I'm considering I'd like to be able to return data that is conditional on the level of authorization of the client. What would be the recommended way of doing accomplishing that and still calling it one API? More specifically, consider the following example for a book access API:
HTTP GET /library/books/{book-name}
Any authenticated client should be able to get (JSON) data for the book, like:
{
"book":
{"book-name":"abc", "author":"someone"}
}
But a specific sub-set of authenticated clients should also be able to get:
{
"book":
{"book-name":"abc", "author":"someone"},
"private-info" :
{"book-status":"on-loan", "price":"$20"}
}
For a given book, any suitably authorized client can also access the "private info" via a direct HTTP GET /library/books/{book-name}/private-info.
Now, assuming a suitable client authentication scheme is in place, I cannot help but think that the HTTP GET /library/books/{book-name} above is actually looking like two API's, distinguished by authorization state on the server regarding authentication. This seems not very RESTful.
Perhaps it would be better to keep the base GET book API the same for all without ever having any "private-info", while offerring authorized clients only access to the private-info URI and returning 403 to all others?
How does this type of conditional data access typically get handled with REST APIs?
There is nothing inherently wrong with your approach - it makes good sense to hide information as you suggest based on the user's authorization. REST says nothing about this - the representation of a resource may depend on user authorization, moon phase or what ever else you can think of.
You can although improve caching if you extract the private information to a separate resource. In this case you would have some rather static content for /library/books/{book-name} which can be cached on the client side. Then you would have /library/books/{book-name}/private-info which would be more volatile and user-dependent - and thus not easily cachable.
Building on this you can include a link to the private information in the original resource:
{
Title: "A book",
Author: "...",
PrivateInfoLink: "http://your-api.com/library/books/{book-name}/private-info"
}
The benefit of this is two-fold:
1) The server can leave out the link if the client does not have access to the private information and thus saving the client from a unnecessary round trip to (not) get the private info.
2) The server is free to change the private-info URL if it needs so later on (it could for instance be different URLs based on the user authorization).
If you want to read more about the benefits of hypermedia then try this: http://soabits.blogspot.dk/2013/12/selling-benefits-of-hypermedia.html
I recently answered a similar question. You can find my answer here.
The bottom line is: You should try to separate business logic from authorization logic always. This means you want to externalize your authorization. There are several ways of doing that.
In your particular case, imagine the list of sensitive fields that only a subset of clients can view changes over time, that would potentially require a rewrite of your API. If you decouple authorization logic from your business logic (API) then you can easily update authorization logic without having to rewrite any code. This is called externalized authorization management (see this great Gartner paper on the topic).
As part of my day-to-day job, I help clients secure APIs and web services using XACML. The best practice is always to keep concerns separate.