OAuth2 user token best practice - oauth-2.0

I'm using the "Code Grant Flow" in order to obtain the token server-side passing the secret. Now I need to send the token from the server to the client, to be able to make AJAX request with the bearer token in the header.
Which is the most safe way to do this?

Any method will do as long as you return it over a secure HTTPs channel.
It would be an application specific call, running between the frontend and backend of a single application, probably based on a session cookie that maintains state between the two of them.

Related

OAuth Authorization Code Flow with PKCE on stateless backend

I'm currently working on a solution where I need to authorize with a OAuth provider that is using Authorization Code with PKCE. I am trying to authorize from my stateless API backend (PHP Laravel shouldn't be relevant though).
The issue I am facing is PCKE sends a code challenge created from a unique hashed code verifier. This works fine until the callback url is hit and I attempt to get the token from the OAuth provider.
When I make a request to get the token I need to send the previous code verifier in order to validate the request and receive the access token.
This lead onto my issue, due to my api backend being stateless I have no way of storing the initial code verifier in session so I can't send it when making a request to the token URL. I have got it working by just hardcoding the code verifier to a known value but this defeats the point.
My question is, is there anyway to use the OAuth Authorization Code Flow with PKCE on a stateless backend?
If you want to keep the described configuration - your PHP backend is an OAuth2 client, I would use the state auth request parameter (RFC) as a key for saving the code_verifier. The state parameter will be returned to you with an auth code.
So you generate random (different) values for state and code_verifier and save them as a key-value pair in a database (or somewhere else). When a response from the OAuth2 server comes, try to find the code_verifier by the state value received from the OAuth2 server.
You can also use your Vue.js frontend as an OAuth2 client, which is stateful, and send an access token to your backend whenever necessary.
Access tokens use to be short lived, so if you need to make more than one request, you will need to take care of generating new ones using a refresh token. Consider that when deciding where to keep the OAuth2 tokens.

OAuth redirect flow server to server token generation for client

I have a rest API service that enables API calls for some resources.
The API calls can be done from an API server using a secret, or from a web client using a bearer token.
In order to get to the web client flow, a URL must be generated by the API server call:
https://www.someapi.com/somelink
The response will be a link with a token I call "action token". This token is passed with the link, for example:
https://www.somepage.com/?action_token=somejwttoken
By entering the link, the action token will be exchanged with an access token, that enables a client to access some pre-defined resources.
I wonder if there is a best practice for such flow.
ONE TIME TOKENS
If using tokens in URLs you should also ensure that:
The token has a one time use
The token is short lived
The token is not guessable - eg make it a UUID
The final access token returned has limited privileges and also a short lifetime
The one time action token may then be available in the browser history or server logs, so be aware of that. Make the actual swap for the proper token a JSON to JSON POST operation, after the page has loaded.
Typically each action token issued would also be stored by the API in a database along with its expiry time, then used to verify links later.
This type of URL solution is sometimes used in operations such as verify email or to enable magic links, where users can quickly access limited data.
OAUTH FLOWS
One time tokens should not be overused and they are of course no substitute for signing the user in properly via OpenID Connect standards, then running an authenticated user session.
SCOPES AND API TO API FLOWS
A more secure option may be to forward JWTs from the original client to downstream APIs, as described in Scopes Best Practices. This enables user context to flow securely and also simplifies code. This may eliminate or reduce the need for any token exchange operations.

Do OpenID Connect id_token and access_token need to be validated if they are obtained by web server?

I am wondering that in the OpenID Connect Auth Code Flow, whether there is still a need to validate the access_token and id_token given they are obtained by my web server rather than by browser (i.e. using back channel rather than front channel)?
By "auth code flow" I am referring to the flow where browser only receives an "authorization code" from the authorization server (i.e. no access_token, no id_token), and sends the auth code to my web server. My web server can therefore directly talk to the authorization server, presenting the auth code, and exchange it for the access_token and id_token. It looks like I can simply decode the access_token and id_token to get the information I want (mainly just user id etc.)
My understanding of the need for validating the access_token is that because access_token is not encrypted, and if it is transmitted through an insecure channel, there is a chance that my web server can get a forged token. Validating the token is basically to verify that the token has not been modified.
But what if the access_token is not transmitted on any insecure channel? In the auth code flow, web server directly retrieves the access_token from the auth server, and the token will never be sent to a browser. Do I still need to validate the token? What are the potential risks if I skip the validation in such flows?
You should always validate the tokens and apply the well known validation patterns for tokens. Because otherwise you open up your architecture for various vulnerabilities. For example you have the man-in-the-middle issue, if the hacker is intercepting your "private" communication with the token service.
Also most libraries will do the validation automatically for you, so the validation is not a problem.
When you develop identity systems you should follow best practices and the various best current practices, because that is what the users of the system expects from you.
As a client, you use HTTPS to get the public key from the IdentityServer, so you know what you got it from the right server. To add additional security layers, you could also use client side HTTPS certificates, so that the IdentityServer only issues tokens to clients that authenticates using a certificate.
In this way, man-in-the-middle is pretty impossible. However, in data-centers in the backend, you sometimes don't use HTTPS everywhere internally. Often TLS is terminated in a proxy, you can read more about that here
When you receive an ID-token, you typically create the user session from that. And yes, as the token is sent over the more secure back channel, you could be pretty secure with that. But still many attacks today occurs on the inside, and just to do a good job according to all best practices, you should validate them, both the signature and also the claims inside the token (expire, issuer, audience...).
For the access token, it is important that the API that receives it do validate it according to all best practices, because anyone can send requests with tokens to it.
Also, its fun to learn :-)
ps, this video is a good starting point

Seperate Authorisation and resource server for openId Connect + OAuth

I will be using a OAuth and openId connect. My application will be having a separate authorization server and resource server. I want to implement a POC.
I have few questions:
1. How to store the received access token in my application? what is best option? to store in DB or session / cookie?
2. How will the resource server validate the access token generated by authorization server?
3. How to implement session management in my application? I read that openId connect is stateless, but to validate the token I need to maintain session, very confused.
I have read a lot but could not find this scenario where Authorization and resource server are separate.
Access tokens are usually short lived. This is done for security purposes to avoid MITM attacks. So in my opinion, unless you are using long lived tokens for some reason(in which case its better to use a database), the best option would be to store the access token in the server session or cookies.
There are basically two ways to do this. Either you invoke the introspection endpoint of the authorization server(IdP) with the access token through resource server, or you can verify the token in the resource server itself using a library(nimbusds, auth0) by validating the token signature and claims. The recommended one is the second option because if there are several resources trying to validate tokens using introspection, the overhead would be too high. Also, some IdPs don't allow introspection through bearer tokens which could be problematic in the case of a public client(no client secret to use in client credentials).
I guess this depends how you application works. If you are using something like servltes, you can store the tokens in server session or cookies through the client application. When the tokens are sent to the resource server they should be send within the request header under Authorization parameter. Not exactly sure about this one.
Hope this helps. Cheers.

Why do you need authorization grant when you can just give the token out directly?

Watching this video, it details in OAuth2 that the client application first has to get the authorization grant from the Authorization server and then use that grant to get a token before being able to access the resource server. What purpose does the grant serve? Why not give the client the token right away after the user signs on with his/her username and password?
Because it is more secure, for some application types.
What you describe is so called authorization-code-flow. It is normally used for "classical" web applications, where only the backend needs to access resource server. The exchange of authorization code to access token happens on the backend and access token never leaves it. Exchange can be done only once and in addition client id and secret (stored on the backend) are necessary.
Single-Page-Applications often use implicit-flow where access token is delivered to the frontend directly in the URL.
See more here:
IdentityServer Flows
EDIT: Q: "I still don't see how it is more secure given that you have to have the grant in order to get the token. Why need 2 things instead of just 1 thing to access the resource? If someone steals the token, they can access the resource anyway – stackjlei"
"Stealing" access token will work independent on how your application acquires it. However, stealing access token on the backend is much more difficult than on the frontend.
Authorization code is delivered to the backend also over the frontend but the risk that someone intercepts and uses it is tiny:
It can be exchanged only once.
You need client-id and client-secret in order to exchange it. Client-secret is only available on the backend.
Normally, authorization code will be exchanged by your backend to access-token immediately. So the lifetime of it is just several seconds. It does not matter if someone gets hold of used authorization code afterwards.
In your scenario there could be two servers, an Authorization and a Resource one.
It could be only one as well, but let's imagine this scenario.
The purpose of the Authorization Server is to issue short lived access tokens to known clients. The clients identify themselves via their CLientID and CLientSecret.
The Authorization Server ( AS ) holds the list of clients and their secrets and first checks to make sure the passed values match its list. If they do, it issues a short lived token.
Then the client can talk to the Resource Server ( RS ), while the token is valid. Once the token expires, a new one can be requested or the expired one can be refreshed if that is allowed by the Authorization Server.
The whole point here is security, Normally, the access tokens are passed in the Authorization header of the request and that request needs to be over https to make sure that the data can't be stolen. If, somehow, someone gets hold of an access token, they can only use it until it expires, hence why the short life of the tokens is actually very important. That's why you don't issue one token which never expires.
You have different type of OAuth. On type doesn't require to use the 'grant' authorization. It depend who are the user/application, the ressource owner and the server API.
This way, you - as a user - don't send the password to the application. The application will only use the grant token to gain access to your ressources.
I think this tuto is a pretty good thing if you want more details
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

Resources