I am currently working with a group of applications that are running on two separate, but equivalent, environments (Referred to as ENV1 and ENV2). I have been using OAuth 2.0 for Authorization and when I receive a response after requesting an access token from the OAuth service (I am making my requests through Postman) I get a response that looks like this from ENV1 and ENV2:
As far as I am aware, I believe that this "token_type": "Bearer" means that when I send in the access_token to my application I need to do so like this:
By sending in the token through the Authorization header, prefixed with "Bearer". This approach works fine on ENV1 but on ENV2 the request fails unless I send in the token alone with no "Bearer" prefix:
If I send in the Authorization header with the "Bearer" prefix, I get a 401 Unauthorized error as the response. This is the help tip that Postman provides(Emphasis mine):
Similar to 403 Forbidden, but specifically for use when authentication is possible but has failed or not yet been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the requested resource.
The problem here is that there IS a WWW-Authenticate header field, and it contains "Bearer", which I would assume is a "challenge applicable to the requested resource" seeing as the token response contained "token_type": "Bearer":
Questions:
Why would this be different between environments?
How is this even possible? The documentation I have found on OAuth 2.0 shows that the "Bearer" prefix is needed for requests like the ones I am trying to make. (for example, in section 2.1 of the documentation here)
From your description, it seems that the environments are not actually identical. E.g. maybe ENV2 is behind a gateway that adds the Bearer prefix to the header. Or the API on ENV2 (or the gateway) is configured to read the header without the prefix.
When the OAuth Server returns the access token, it gives you the type - a bearer token. That type means, that the token is just this - a bearer token - as opposed to a Proof-of-Possession token. When you send a bearer token to an API, you don't have to provide any additional information that would prove that you are the owner of the token. (you can compare bearer with the DPoP standard)
The Bearer Token Usage standard does require you to use the prefix Bearer in the authorization header (as you pointed out), but it doesn't mean that all the APIs and gateways implement that standard correctly, or that they use that standard at all.
To summarize:
it's up to the gateway/API to decide in what format they want the Authorization header, and that has nothing to do with the type of the token (a bearer token). It's nice when they use standards, but they don't have to.
In your setup, there must be some kind of difference between the environments if the same request is treated differently between them. If you own the environments you should investigate what is configured differently. If you don't own them, you should contact the owner's support to solve the issue.
Related
As a preface I'd like to claim I have some understanding of how the HTTP-supported authentication is supposed to work according to RFC 7235.
I am specifically interested to know how a client is supposed to know, after authenticating, which URIs on the server it is expected to provide same authorization (through the Authorization header) bearer for? Furthermore, is there any provision by HTTP to assist client in determining which Authorization headers it (the client) may have available (through whatever means it acquires them -- "login" form/dialog etc), would go with which realm(s)?
A realm doesn't seem to be specified in the form of an URI or even a regular expression of an URI, it's a value the interpretation of which appears to be left to the HTTP client application. Of note, a "Protection Space (Realm)" is defined, quoting:
A protection space is defined by the canonical root URI (the scheme and authority components of the effective request URI (see Section 5.5 of RFC7230) of the server being accessed, in combination with the realm value if present.
The above is all well and good, but it doesn't facilitate client mapping realms to URIs that may require authorization.
Say my Web server returns a response with status code 401 and the WWW-Authenticate: Bearer realm="The hangout" header line, for a request with a given URI, let's say /foobar. That makes it obvious that subsequent requests to the particular URI must include Authorization header line corresponding to solved challenge (as the client authenticates the user). No problem there. But what about e.g. requests with URI(s) that have the same pathname - those starting with /foobar/ -- is there an implication here that the same Authorization value is expected for these as well? What about entirely unrelated URI pathnames [on the same server]?
It would seem beneficial for the kind of authorization negotiation HTTP already does, to somehow relate or facilitate said relation of realms to URIs. But maybe I am missing something very obvious. Does HTTP do something along of what I am describing? Does it facilitate it in any way, at least, beyond leaving it entirely to the application? How would one realistically let the client determine which authorization bearer to send for which requests? Must it always get a 401 and a challenge response first, before knowing for sure requests to the particular URI and only said URI, must include related authorization bearer?
HTTP is a stateless protocol that deals with a request-response pair. The protocol does not deal with any information that would describe the concept of a "page", "site", "application", etc. Even though it deals with hypermedia, the protocol itself doesn't go beyond the concrete request. This means that you won't get any information from the protocol itself about any other paths under the same domain that are in the same authentication realm. This is left to the documentation of APIs or websites.
It seems to me that your research is centered on one type of authentication process that we call basic auth, know they are some other ways to authenticate a user and that they might suits your needs better as basic auth is kinda old as you can see on that RFC you linked.
To my understanding, the principle behind basic auth is to have a simple process based on challenges. When your client asks for a resource and that resource is protected by authentication, the server responds with a challenge : 401 Unauthorized with a header WWW-authenticate: Basic realm="some realm". The client then know the resource is restricted and depending on the realm, knows if it can have access (or asks the user for credentials for that realm), and try to access with a basic auth header : Authorization: Basic viFWGrwehryfviehtNRBRGWrwGERThRGE. You then repeat that process every time you need a resource.
HTTP and basic auth don't implement any sort of deeper and more complex system for authentication like you're searching for. It's one of the simplest system as its name implies and has not a lot more to offer. I'd even add that it's one of the riskier way to authenticate a system (even using SSL cert and cert pinning) as the client must send credentials for every single authenticated resource request.
In case you want to search other ways to authenticate requests, here are some :
OAuth (2.0) (most secured and complex)
Bearer (JWT or session tokens)
API keys
I am new to Here and am trying to make my first API call but I keep getting back this error:
{"Type":"Unauthorized","Message":["Bearer token invalid. Bearer missing or bearer value missing."]}
Here's the URL that I'm using to call the API:
https://fuel-v2.cc.api.here.com/fuel/stations.json?apiKey=${hereApiKey}&prox=${lat},${lng},1600
I have also tried including the api key in an authorization header and get the exact same thing. I've tried with apikey= and apiKey= and the results are the same. I've also tried moving the apikey param to after the prox param (though I know that shouldn't matter). I feel like I'm following the documentation when it says that I can use api key authentication for this call and that app code authentication is deprecated, so I'm not sure what I'm doing wrong.
I am currently on a Here Freemium plan and making this call from a Node JS server application.
The token expires in 24 hours, you need to generate a new token and test again
In order to use OAuth token authentication please use the below request
https://fuel-v2.cc.ls.api.here.com/fuel/stations.xml?prox=52.516667,13.383333,5000
And in header please include
Authorization = Bearer "Oauth token"
other way to include the token is -
https://developer.here.com/documentation/fuel-prices/dev_guide/topics/request-here-environments.html
I'm creating a RESTful service to provide data to a web application. I have two related questions about this.
1. How to deal with unauthorized requests?
I'm intending to respond to requests with the following codes:
Is the resource open and found? 200 OK
Do you need to be authenticated to access the resources? 401 Unauthorized
Don't you have access to a category of resources? 403 Forbidden
Do you have access to a category of resources, but not to this specific resource? 404 Not Found to prevent people from getting to know the existance of a resource they do not have access to.
Doesn't the resource exist? 404 Not Found
Is this a recommended way for a RESTful service to behave?
2. What WWW-Authenticate header should 401 responses supply?
I read on Wikipedia (probably not the most accurate resource, but it works for me) that a 401 response must include a WWW-Authenticate header, however upon further searching I couldn't really find any resource that stated what this value means and what it should be.
I found several SO questions and forum topics about this header and they all seem to be about OAuth, suggest against using 401 status codes or say you can just make something up.
What is the correct value this header should contain?
To answer your questions:
How to deal with unauthorized requests?
The way you described it is pretty much the recommended way for a RESTful service. As far as I can see there is absolutely nothing wrong with that.
What WWW-Authenticate header should 401 responses supply?
In general the WWW-Authenticate header tells the client what kind of authentication the server will accept. If the client makes an unauthorized request, which means he is sending a request with a missing or invalid Authorization header, the server will use WWW-Authenticate to tell the client what authentication scheme he will accept (i.e. Basic, Digest or OAuth) and for what realm.
Imagine it like some kind of identification question or challenge on the part of the server, i.e. something like "Who are you?" or "Prove who you are by providing credentials in the following way!".
For Example: WWW-Authenticate: Basic realm="My App"
Here the server tells the client that he uses an authentication scheme named Basic. The realm is nothing more than some string that identifies a protected space on the server.
Based on my research (googling) i decided to send: Newauth realm="use login token".
The website http://greenbytes.de/tech/tc/httpauth/#unknown has test cases for different auth methods and i haven't found anything which describes 'get auth token' and therefore i think it is a 'Newauth'.
Also important for me: This doesn't create a login prompt on client side.
On every call to my REST API, I require clients to pass user's facebook access token, which authenticates the user. What's best practice for passing this token?
maybe as a parameter behind the HTTP question mark
GET /api/users/123/profile?access_token=pq8pgHWX95bLZCML
or somehow in the header of the request, similarly to HTTP basic authentication
maybe a third option? (I've excluded passing it in a JSON because I want the token get passed in GET calls as well, so JSON wouldn't fit there I think)
If you look at the API endpoints provided by all popular OAuth providers (Google, Facebook, Pocket, Git etc), you'd see that they all have HTTPS endpoints.
The ways in which you can pass an access token to the provider are -
i) As Query Parameter -
https://yourwebsite.com/api/endpoint?access_token=YOUR_ACCESS_TOKEN
ii) In the request header -
GET /api/users/123/profile HTTP/1.1
Host: yourwebsite.com
Date: Tue, 14 May 2013 12:00:00 GMT
Authorization: <YOUR_ACCESS_TOKEN>
These two are approaches that are generally supported by most APIs. You can think of doing the same.
iii) Pocket API does not use GET at all. They use POST for all their requests, even for retrieving data. Check this link to see their documentation. Notice that they use POST for retrieving data and pass JSON parameters.
I need to authenticate a client when he sends a request to an API. The client has an API-token and I was thinking about using the standard Authorization header for sending the token to the server.
Normally this header is used for Basic and Digest authentication. But I don't know if I'm allowed to customize the value of this header and use a custom authentication scheme, e.g:
Authorization: Token 1af538baa9045a84c0e889f672baf83ff24
Would you recommend this or not? Or is there a better approach for sending the token?
You can create your own custom auth schemas that use the Authorization: header - for example, this is how OAuth works.
As a general rule, if servers or proxies don't understand the values of standard headers, they will leave them alone and ignore them. It is creating your own header keys that can often produce unexpected results - many proxies will strip headers with names they don't recognise.
Having said that, it is possibly a better idea to use cookies to transmit the token, rather than the Authorization: header, for the simple reason that cookies were explicitly designed to carry custom values, whereas the specification for HTTP's built in auth methods does not really say either way - if you want to see exactly what it does say, have a look here.
The other point about this is that many HTTP client libraries have built-in support for Digest and Basic auth but may make life more difficult when trying to set a raw value in the header field, whereas they will all provide easy support for cookies and will allow more or less any value within them.
In the case of CROSS ORIGIN request read this:
I faced this situation and at first I chose to use the Authorization Header and later removed it after facing the following issue.
Authorization Header is considered a custom header. So if a cross-domain request is made with the Autorization Header set, the browser first sends a preflight request. A preflight request is an HTTP request by the OPTIONS method, this request strips all the parameters from the request. Your server needs to respond with Access-Control-Allow-Headers Header having the value of your custom header (Authorization header).
So for each request the client (browser) sends, an additional HTTP request(OPTIONS) was being sent by the browser. This deteriorated the performance of my API.
You should check if adding this degrades your performance. As a workaround I am sending tokens in http parameters, which I know is not the best way of doing it but I couldn't compromise with the performance.
This is a bit dated but there may be others looking for answers to the same question. You should think about what protection spaces make sense for your APIs. For example, you may want to identify and authenticate client application access to your APIs to restrict their use to known, registered client applications. In this case, you can use the Basic authentication scheme with the client identifier as the user-id and client shared secret as the password. You don't need proprietary authentication schemes just clearly identify the one(s) to be used by clients for each protection space. I prefer only one for each protection space but the HTTP standards allow both multiple authentication schemes on each WWW-Authenticate header response and multiple WWW-Authenticate headers in each response; this will be confusing for API clients which options to use. Be consistent and clear then your APIs will be used.
I would recommend not to use HTTP authentication with custom scheme names. If you feel that you have something of generic use, you can define a new scheme, though. See http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p7-auth-latest.html#rfc.section.2.3 for details.
Kindly try below on postman :-
In header section example work for me..
Authorization : JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyIkX18iOnsic3RyaWN0TW9kZSI6dHJ1ZSwiZ2V0dGVycyI6e30sIndhc1BvcHVsYXRlZCI6ZmFsc2UsImFjdGl2ZVBhdGhzIjp7InBhdGhzIjp7InBhc3N3b3JkIjoiaW5pdCIsImVtYWlsIjoiaW5pdCIsIl9fdiI6ImluaXQiLCJfaWQiOiJpbml0In0sInN0YXRlcyI6eyJpZ25vcmUiOnt9LCJkZWZhdWx0Ijp7fSwiaW5pdCI6eyJfX3YiOnRydWUsInBhc3N3b3JkIjp0cnVlLCJlbWFpbCI6dHJ1ZSwiX2lkIjp0cnVlfSwibW9kaWZ5Ijp7fSwicmVxdWlyZSI6e319LCJzdGF0ZU5hbWVzIjpbInJlcXVpcmUiLCJtb2RpZnkiLCJpbml0IiwiZGVmYXVsdCIsImlnbm9yZSJdfSwiZW1pdHRlciI6eyJkb21haW4iOm51bGwsIl9ldmVudHMiOnt9LCJfZXZlbnRzQ291bnQiOjAsIl9tYXhMaXN0ZW5lcnMiOjB9fSwiaXNOZXciOmZhbHNlLCJfZG9jIjp7Il9fdiI6MCwicGFzc3dvcmQiOiIkMmEkMTAkdTAybWNnWHFjWVQvdE41MlkzZ2l3dVROd3ZMWW9ZTlFXejlUcThyaDIwR09IMlhHY3haZWUiLCJlbWFpbCI6Im1hZGFuLmRhbGUxQGdtYWlsLmNvbSIsIl9pZCI6IjU5MjEzYzYyYWM2ODZlMGMyNzI2MjgzMiJ9LCJfcHJlcyI6eyIkX19vcmlnaW5hbF9zYXZlIjpbbnVsbCxudWxsLG51bGxdLCIkX19vcmlnaW5hbF92YWxpZGF0ZSI6W251bGxdLCIkX19vcmlnaW5hbF9yZW1vdmUiOltudWxsXX0sIl9wb3N0cyI6eyIkX19vcmlnaW5hbF9zYXZlIjpbXSwiJF9fb3JpZ2luYWxfdmFsaWRhdGUiOltdLCIkX19vcmlnaW5hbF9yZW1vdmUiOltdfSwiaWF0IjoxNDk1MzUwNzA5LCJleHAiOjE0OTUzNjA3ODl9.BkyB0LjKB4FIsCtnM5FcpcBLvKed_j7rCCxZddwiYnU