I have front end app which call to back-end service and redirect user to Auth0 login, after success login Auth0 calling my back-end service and passing JWT token, I'm passing this token to my Front-end. Every time front-end calling to back-end services I'm calling Auth0 validation service.
Is it possible not to call each time Auth0? can I validate Auth0 token on my back-end or I need to sign my own token?
what is the best flow?
ok, so Auth0 has a keys [https://auth0.com/docs/tokens/json-web-tokens/json-web-key-sets][1]
there is a [library https://github.com/auth0/node-jwks-rsa/tree/ee90de2a6dbf4668081f6d7fa4b0afae58fbadfb/examples/passport-demo][1] that can fetch this keys and validate token without making repeatable calls to Auth0.
Related
Consider:
An SPA or a statically generated JAMStack website (written in Vue/Nuxt).
A REST API (Node + Express) running in the cloud.
The website is being served through a CDN.
We are required to add a Social Sign-On functionality for user convenience. The API already authenticates users with a credential based JWT (access/refresh) token flow. Social sign-on will be in addition to that.
We have selected the Authorization Code Flow as the mechanism for this implementation (instead of PKCE, because we want the SPA to use the API's access tokens instead of the authorization provider's).
Our flow is as follows:
The user clicks on a button and is directed to the Identity Provider's (in our case, Google) website to prove its identity. We provide a randomly generated state token as a request parameter to prevent CSRF attacks.
On the IdP's authentication page, the user submits their credentials and if successful, the user is redirected back to our website (the SPA) with the state token and a code as url parameters.
We then match the state value with the one that we generated on our app to defeat CSRF attacks.
We send the code value to our API in an AJAX request.
The API takes this code and our client secret and exchanges them for an identity taken with the identity provider (disregarding the access tokens as we only require proof of identity).
If the user identity is verified, the API generate a pair of access and refresh token and sends them to the SPA. (If the user does not exist in our database, it is added and similarly returned tokens for our API).
NOTE: We do not store the identity token received from the IdP on the server at all.
One receiving the response, the SPA stores the access token in localStorage, (the refresh token is stored in an HTTP only cookie by the API).
All further requests to our API from the SPA are made with the access token issued by our API, once both the refresh token and access tokens expire (through logout or timeout), the user has to re-initiate the authentication flow from step 1.
I have two questions:
Assuming that all communication between the IdP and SPA, the SPA and the API, and the API and the IdP is happening over TLS, are there any security vulnerabilities present in our process?
This one perplexes me more, how do you persist the state token that we generate during the initial request to the authentication server between page redirects? (from when we leave our SPA to authenticate on IdP's webpage to when the IdP redirects us back to our SPA). Is localStorage a secure enough option? If not, would sessionStorage suffice?
For a new project I would consider using the BFF pattern to avoid dealing with tokens at all in the SPA/browser. Because there is no secure way to deal/store tokens in the browser.
Do check out these resources for more details about why this pattern is recommended for new projects:
alert‘OAuth 2 0’; // The impact of XSS on OAuth 2 0 in SPAs
Using the BFF pattern to secure SPA and #Blazor Applications
The BFF Pattern (Backend for Frontend): An Introduction
I have an API http gateway (at say https://example.com) integrated with an API REST gateway which uses a Cognito authorizer. All of this to serve a single-page React application. The behaviour is as expected:
I launch the Cognito hosted UI and sign in,
It redirects to the url https://example.com/#id_token=123
If I use PostMan, I can access that url if I pass that id_token in the Authorization header.
Now my question is: how can I pass the header automatically after signing in so I can visit https://example.com?
I have spent a long time on this and have found many similar posts without an answer:
How to use the code returned from Cognito to get AWS credentials?
How can I link cognito token and API authentication header automatically?
AWS Cognito hosted UI returning id_token in URL
How can I make the redirect_uri of AWS Cognito (Hosted UI) authenticated?
Set Authorization header when redirecting client from Cognito to AWS API Gateway
How do I handle a Cognito auth redirect for a Lambda / API Gateway for UI?
We faced the same question a couple of years ago. Our solution was creating a proxy (using API Gateway and Lambda) that "moved" the id_token (stored in a cookie) to the Authorization header for every request to the server. It was ugly, but it worked.
BTW, getting id_token in the URL is how Implicit Grant works. But Implicit Grant is generally considered less secure than Authorization Code Grant. We have since migrated from Implicit Grant to Authorization Code Grant. However, we continue to use the proxy pattern (again using API Gateway and Lambda) as follows.
Exchange the returned code for access_token and id_token at the Cognito user pool's token endpoint. Store the tokens in a DynamoDB table with session_cookie as the partition key. Return the session_cookie as a cookie (with HttpOnly, Secure and SameSite=Strict) to the browser.
For each request from the browser, use the cookie to find the token in the DynamoDB table and put the token in the Authorization header.
Question
I got a problem with understanding some basic thing about auth0, probably someone can help me out.
In the tutorial SPA + API one of the first lines in the TDLR is this:
Both the SPA and the API must be configured in the Auth0 Dashboard
I dont understand why I need to configure the API on Auth0. My code seems to work so can anyone help me understand if I do something wrong or what the advantages are if I actually add a custom API in my dashboard?
Setup
SPA (React)
Auth0
REST API (ktor)
What I do
Created a SPA on Auth0
Login on my SPA through Auth0 to get a JWT (google token)
Sending the JWT as authentication bearer in my calls to the REST API
REST API verifies the JWT token with a JWK provider using the Auth0 url mydomain.eu.auth0.com/.well-known/jwks.json.
Authentication seems to work
Great question, I am assuming that your authentication request includes audience parameter which represents your custom API(Rest API)right now. In oauth2 terms, it is called Resource Server. Each resource server can have many permissions which you include in the scope when initiating the authentication request. Let's step back and talk about the token format. Auth0 issues token in two formats:
Opaque strings: When not using a custom API
JSON Web Tokens (JWTs): When using a custom API
https://auth0.com/docs/tokens/reference/access-token/access-token-formats#how-does-all-this-affect-the-token-format-
As explained above link, the token format depends on the audience (Custom API) parameter. Therefore, when the authentication request includes audience, auth0 issues JWT token with all necessary permission. Then, you need to validate the JWT token in your API server before returning the resources to your front end client.
It should make sense why you need to create custom API in auth0 and define permissions. If you do not create custom API in auth0, there is no way to know what kind of permission you need in the token which will generate an error(invalid audience specified)
I have 3 services (in the real much more):
Authorization service (uses OAuth 2.0)
Frontend service
Resource service
and client (web-browser).
I store session_id, access_token and refersh_token in cookies of the user's web-browser. The user goes to Auth service, signs in and gets these tokens. After his web-browser is redirected to Frontend.
Frontend and Resource services can't validate tokens because they know a nothing about it, so they must make a request to Auth service.
The current scenarios:
The user (web-browser) sends a request to Frontend service, the Frontend sends a request to Auth service to validate access_token. If it's invalid the Frontend sends a request to refresh token using refresh_token.
If the Frontend needs an access to Resource service to process a request then the Frontend sends its client_id and access_token to Resource service. The Resource service sends a request to the Auth service to validate an access_token too.
Are my thoughts right? Or it has simpler schema?
P.S. All services use RESTful architecture.
OAuth talks about how the tokens be exchanged. What you have mentioned it seem liek you are talking about using implicit grant, which is little less secure and you may think of opting for authorisation flow.
Other than that, in microservices when you have many services and one user request pass through many downstream services, verifying the token with auth provider at each and every step might become a bottleneck.
There are ways out there by which you can skip this call to auth server and still validate the sanctity of the token without making an explicit call.
One way is to make use of JWT. These tokens are signed by the Auth provider and your services have keys which can help you validate if the token is modified on it way, and token itself has all the information you need to ensure validity of it, like expiry time, intended audience, clients, roles etc.
On login you get AT and RT. AT could be passed along to downstream for authentication and authorization and RT could be used when AT is expired.
You only need to talk to auth provider at the time of login and when you need to refresh the token.
You can read more about the JWT OAuth2.0 with JWT and OIDC to get more information around it
I'm developing an Android app that consumes a REST service that uses OAuth protocol. In the first activity, app shows a login screen. This is the flow:
1) User puts her username and password.
2) App makes a request to REST service, providing username and password.
3) REST service check the credentials and if are correct, ask for an access_token to my OAuth2 provider server.
4) REST service answers to the app providing the access_token and the refresh_token
5) In the next requests to the REST server (to get data like people, articles...) app will provide the access_token and the refresh_token.
6) When REST service process a request, will validate the access_token (using an token info endpoint of my OAuth server).
7) If the access_token is correct and has not expired, REST service will return the data that the app were asking for.
When REST service detects that access_token has expired, asks for another with using the refresh_roken.
Now, my questions:
When REST service retrieve a new access_token after the old one expires, has the REST service send it to the app in that response?
If so, has the app check, in each request/response, if new a new access_token has been sent from the REST service?
I don't know if I'm in the right way, I'm trying to understand the flow.
Thanks.
Assuming there's no browser involved and the app (aka. Client) uses what is called the Resource Owner Password Credentials grant, the flow is:
the User (aka. Resource Owner) provides his/her username and password to the Client
the Client makes a Token Request to the Authorization Server, providing username and password
the Authorization Server checks the credentials and if they are correct, it provides an access token and optionally a refresh token to the Client in the response
in the requests to the REST server (to get data like people, articles...) the Client will provide the access token
when the REST service process a request, it will validate the access token calling the token validation endpoint of the Authorization Server or by validating the token locally (e.g. if the access token is a JWT).
if the access token is correct, has not expired and has the right permissions (aka. "scopes"), the REST service will return the data that the Client was asking for
when the Client detects that access_token has expired (e.g. because the REST server returns an error), it asks the Authorization Server for another access token using the refresh token using the so-called Refresh Token grant/flow
OAuth 2.0 flows:
An application registers with the auth provider e.g. Facebook, Google, etc with app name, website and callback/postback URL
The application receives the client id and secret from the auth provider
The application user accesses the auth provider for authentication and user approves the resource permissions
The auth provider returns the auth token with respect to the user permissions to the application
The application accesses the resource provider using the auth tokens
The resource provider returns the protected resources after validating the auth tokens to the application
Do comment if you need more understanding!