I am implementing an API that is going to be authenticated using JWT. I am curious to what are best practices on the response to the creation of the JWT. Specifically, I would like to include a payload in the response body(some user related information that I do not want to put in the payload section of the token), and send back the token in the Authorization header. Other options I see are to include the token as well as the user information in the response body, or make the client user make 2 http calls, one for the token, the other for the user information. I would like to know what is the proper way of handling this scenario.
Related
this is my first question on StackOverflow. 😀
I'm currently creating a Discord Bot with a Dashboard and a private API for my service.
The flow I'm trying to create is the following
User logs in with Discord OAuth2 and gets his access_token
-> Client stores his access_token
-> When doing an action on the Dashboard and commit it, make an API call and pass his access_token
-> My API then check if he has the permission to commit it
(by doing a request to Discord's API with his access_token)
-> Realise the action if allowed
Because the user needs to send his access_token, I need to know how I'm supposed to recieve and use it safely, and following the best practices.
Those are the two way I found :
Use a custom HTTP Header like Discord-Access-Token: <access_token> and then process-it easly
to use Authorization: Baerer <access_token> (even tho this is not
an Authorization but something I need to check if the user is allowed
to use the API). + This is not really following the flow in FastAPI...
Does someone knows what is the best thing to use? Thanks in advance!
even tho this is not an Authorization but something I need to check if
the user is allowed to use the API
So Authorization in simple terms...
Think of your service as something that covers everything you do even doing stuff with tokens on Discord.
I would use the Authorization header, because it is standard, unless you have another token, because you cannot send multiple ones in a single request except if you package them together. If you have a different header, then the request can be modified or cached by proxies. https://stackoverflow.com/a/43164958/607033
As far as I understand Basic and Bearer are not the only types of Authorization, you can have a custom type too. If Bearer does not cover the term you need, then write something like DiscordOAuth2.
The Authorization header name is a misnomer, in the same category as the misspelling as 'Referrer'. The purpose of the Authorization header is actually authentication.
Also not that it's Bearer not Baerer.
I am building an oauth login flow and I am not sure if I have done it wrong because I will need to send the bearer token back via redirect URL, like /oauth2/redirect?token=[TOKEN]. But isn't it not recommended to have token passed along through URL? As it is pointed out in this thread:
Don't pass bearer tokens in page URLs: Bearer tokens SHOULD NOT be passed in page URLs (for example, as query string parameters).Instead, bearer tokens SHOULD be passed in HTTP message headers or message bodies for which confidentiality measures are taken. Browsers, web servers, and other software may not adequately secure URLs in the browser history, web server logs, and other data structures. If bearer tokens are passed in page URLs, attackers might be able to steal them from the history data, logs, or other unsecured locations.
I must have missed something in the whole flow and would like to understand more about this matter. Any input is appreciated!
UPDATE
Might not be correct but this is my understanding after some digging. The three means to pass token:
URL (not preferable)
Auth header
Request body
But under the oauth redirect use case, option 2 and 3 not feasible. So option 1 is the only option available. If really needed, token can be encrypted to ensure security.
I think this only means, that you should not use a GET request when the server requires the token, instead you should use POST or whatever is appropriate. In a GET request the parameters are included in the URL and those can end up in logs or other histories, other request types will send the paramters separat from the request URL.
P.S. BTW if you are not implementing the OAuth server yourself, you won't have to send a redirect url containing the token.
The basic auth header which provides a little extra security as it's required to be through TLS:
In the case of a "Basic" authentication like shown in the figure, the exchange must happen over an HTTPS (TLS) connection to be secure.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication
Also, the headers aren't logged in easy places like browser history.
From the spec,
it SHOULD NOT be used
unless it is impossible to transport the access token in the
"Authorization" request header field or the HTTP request entity-body.
https://www.rfc-editor.org/rfc/rfc6750#section-2.3
I would like to ask little theoretically.
I have an angular6 + spring app that has its own client, app-specific client data.
These data can be divided into two groups
managment-data: Like client roles that allow client to visit different parts of app
client-data: personal settings, history of activities etc.
Because I would like to make login as user-friendly as possible, I would like to implement facebook login.
After user click "FB login button", facebook returns me some-user info and mainly a security token. How could I use this to securely communicate with my BE.
When someone sends request to BE, I need to be sure, that its the same person that logged in to facebook.
If I send this token as part of request, what stops possible attacker to somehow obtain token and then impersonate original user?
In what form I should send data I got from Facebook to my own server?
How should I work with token on server?
How can I validate its authenticity?
Thank you for answers
Filip Å irc
You should look into the usage of OpenID Connect along with OAuth protocol. It allows you to authenticate the user to your client application (Angular6 + Spring app) to verify the user details.
When you are sending an access token to access a certain resource, you should avoid sending it as a request parameter. Usually it is encouraged to send it under the Authorization header of the request as a bearer token. However, if you want it to be extra secure, you could encode the token before sending so that it would be difficult to decode it and steal any valuable information.
Also, when you are sending sensitive information, it ise better to send them in the form of a JSON Web Token (JWT). You can use a third party library to create a jwt to include the information that need to be sent to the server. You can sign the jwt with your own signature which can be validated later. Refer https://www.rfc-editor.org/rfc/rfc7519 for detailed information about jwts.
You should use the claims in your access token to grant a user access to the resource you are protecting. Since most of the tokens are sent in the form of jwts, you can decode them and get check the necessary claims such as scopes, audience (client app), subject (user), etc.
Most importantly, you should validate the signature of the token sent from Facebook to make sure its an authentic one. For this, you have to get the public key details from Facebook's jwks endpoint and validate the signature using a third party library (auth0, nimbusds, etc.). Facebook's digital signature will be unique and this verification process is the best way to ensure the security. Also, you can check whether certain claims in the token match your expected values to validate the token. This can also be done through libraries such as ones mentioned above. Here's auth0 repo for you to get a general idea.
I maybe missing an important piece of jwt concept but I'm having a hard time finding info on where the server is supposed to include the generated json web token in the response and where the client is supposed to include it in the subsequent requests. Are there any rules/guidelines/best practices on that?
The JWT should be sent to the client in the response body. In the subsequent requests you've got to include an header field called Authorization with the token.
Check this link for more details.
Folks,
What is a simplest way to track consumer applications accessing RESTful API services inside department.
We do not restrict access - no authentication/authorization - open for invocation, trusted environment.
No tools like OAuth AuthZ servers or API management yet... but might be heading there at some point.
For now we thought to request consumers just to include some custom HTTP Header like X-Client-Id and log it on the server side for stats etc..
But knowing that in the future we might want to switch to more standard ways of doing things ... what would be best alternative to have to change less code in the future ?
Have the "clientId" in the Authorization: OAuth token (like access token)
Have JWT token in the Authorization header (looks too much - signing,base 64 etc for simple client id tracking ...)
Any ideas would be appreciated
We recently implemented this for one of our REST platforms and we used a combination of BOTH the points you mentioned, meaning Authorization header & JWT token. Although, JWT is ONLY for authentication and GETTING an access_token (oauth token) which is later used with calling actual resource apis. I will discuss how we handled this situation and you can decide on how you want to implement it.
1) Authentication
Client sends a JWT to your authentication service (/api/oauth2/auth). (If you want more reading on JWT, you can read here and here of how JWT is implemented by google and how you can use spring-security-jwt libary to handle all the signing and encrypting/decrypting). You get the "clientId" out of JWT after decrypting and verifying the signature and after server does all the authentication, you respond back with a 'refresh_token' and an 'access_token'. Server will save the access_token as well and map it to the clientId so that when client makes requests using access_token, you can know which client is making the request. The access_token expires in some time (ideally in an hour) and when it expires, the client uses the 'refresh_token' to get a new access token by posting refresh_token to some refresh token url (/api/oauth2/auth/token)
2) Authorization
Client takes the 'access_token' and uses the access token to make all the subsequent requests on all other apis (/api/*). Ideally, the access_token is sent as a part of the "Authorization" header. Server uses request filters (if you are using JAX-RS, you can use something like ContainerFilterRequest to add filters to specific url patterns and intercept them) to filter EACH request and parse out the Authorization header value. You will get the access_token from the header and from the access_token you can get the clientId that you mapped in step 1). You can do other authorization logic in the security filter and if everything goes through, you can use this information to LOG that clientId and the request that the client made.
This way you can kill 2 birds with one stone : Implement a security layer & log the information about customers (what calls they are making, how many time etc. etc.). In case you don't want to implement security filter just yet (as you mentioned it might be in the future), for now, the clients can just pass on the "clientId" (base64encoded or not, upto you) as a part of "Authorization" header. If all the calls are from a "trusted" network, it should be ok, although not as secure. This way, when you ACTUALLY implement a JWT and Oauth based security layer, all you have to do is change your ContainerFilterRequest logic to parse out access_token instead of client id (as mentioned in step # 2).
I hope this helps ! For more information on security filters you can have a look at this answer: Basic Authentication of a resource in Dropwizard. It says dropwizard, but it mostly talks about JAX-RS.
To implement full AuthN/AuthZ layer for consumer tracking would be an overkill for now.
We thought to use either to Authorzation header to pass custom client_id token:
Authorization: Custom <Client_Id>
or to use some limited version of JWT (no signatures as there no intent to validate them)
as access token
Authorization: JWT <JWT>
Where JWT could be:
{"alg":"none","typ":"JWT"}
{
"iss":"Client_ID",
"aud": REST Service URI,
"iat":1328550785
}
I do not see description of access_token format in the specification https://datatracker.ietf.org/doc/html/rfc6749#section-1.4
Are there any contraints to use JWT as access token?