JWT token for multiple websites - authentication

How can I have a single JWT token be shared among multiple websites. I assume that the first thing would be to have the same secret on all websites.
If user logs in on site A and a token is generated I want to use the same token for website B on a totally diferent domain.
Can it be done?

What you want can be done, but not with a single JWT token. A JWT token is intended for a certain service or application indicated by the audience (aud) claim. You cannot use the same token for another application or service.
What typically happens to make your SSO scenario work, it that the user logs in to the token issuing (authorization) server. As long as that session is valid, the user can acquire tokens for all applications the server can issue tokens for.
So, when the user logs in to the first application, the authorization server sets a cookie to establish a session. When the user navigates to the second application, the application redirects him/her to the authorization server for authentication. The authorization detects the session cookie and does not prompt to user to log in again, but issues a new JWT token for the second application.

Related

ID token usage when using "Log in with Google" in a mobile app

Suppose that I have a mobile app with a frontend and a backend server.
My understanding is that -- when a user logs in the app with "Login with google", the frontend sends a request to the google auth server, and gets back an ID token. The documentation says that the frontend can then send the token to the backend server to establish a session. I imagine that means the token can be used in session-based authentication?
If I were to use token-based authentication (as opposed to session-based), do I just attach the ID token in every server request, and have the backend verifies it each time when processing a request? this page suggests the ID token should not be sent to the backend API. Which leaves me wonder what the correct procedure is for token-based authentication when using log in with Google.
So my question is: Does my server need to create an access token from the ID token from Google, and send it to the frontend, so the frontend can attach that access token in the API requests for authentication?
Thanks
Login with Google is an identity provider (IDP) operation. A full OAuth solution, including an authorization server (AS) looks like this:
Mobile app uses system browser to redirect to AS
AS returns a redirect response to the system browser, which routes to the IDP
User signs in at the IDP
IDP returns an authorization code to AS
AS swaps it for IDP tokens and carries out validations
AS issues a set of tokens to the app. This includes an access token (AT) with whatever scopes and claims are needed for business authorization to work.
Mobile app sends AT in API requests
API authorizes using scopes and claims from the access token
So ideally plug in an authorization server, to get this out-of-the-box behaviour. Another option is to implement your own token service, and issue your own tokens. That is less recommended though, since it requires more detailed understanding of the underlying security.

Separate authentication and authorization servers for SPA app

I have
UI (a single page app)
an external authentication server
my own authorization server
resource server (my own backend APIs)
Here's what I am trying to do
UI/User gets an AuthN token from the external authentication server.
UI sends the AuthN token to get the an AuthZ token from my own authorization server
UI uses the AuthZ token to retrieve data from the resource server
But the problem is I don't know if the user is still authenticated anymore because I stopped using the AuthN token from step 3. Should I use both tokens together? or somehow consolidate the 2 tokens into one? Hope to get some ideas from here. Thanks!!
COMPONENTS
This is the standard way of managing components:
UI makes an OpenID Connect redirect to the Authorization Server (AS)
AS makes a second OpenID Connect redirect to the authentication system. There could be more than one of these, eg Google, Facebook.
After user sign in the AS issues the same tokens for your UI and resource server, regardless of how the user signs in. The UI sends access tokens to the resource server which can authorize based on scopes and claims received.
Unless you have special reasons, do not use foreign tokens from authentication systems in your own applications. This is because you are not in a position to control their contents.
OPENID CONNECT RE-AUTHENTICATION MECHANISMS
The OpenID Connect prompt and max-age parameters can be used to control how frequently the user is prompted to re-authenticate, and the auth_time claim can be issued in ID tokens to inform the UI of the last authentication time.
For example your app could use access tokens that last 15 minutes. Whenever they expire you could send a request with a prompt-none parameter to see if the user is still authenticated. If not then you will receive a login_required response and you could then redirect the user to re-authenticate.
SINGLE LOGOUT
Knowing if the user is still authenticated suggests you need to know if they signed out in another app. OpenID Connect has four Single Logout Mechanisms that you should be aware of, and which may possibly work for your scenario.
This is a technical area that has never worked perfectly in any Single Sign On technology though. This may be because you do not control all apps, or because of technical limitations, eg Google may not inform the Authorization Server if the user signs out of Gmail.
SUMMARY
Your apps should only use the authorization server tokens. Use OIDC request parameters to control when the user must re-authenticate.

Does Cognito cache the federated ID data

I am integrating my client's organization authentication in to one of their web application via ADFS. I integrated the Cognito pool with ADFS and the authentication seem to happen fine. However, I have the following question:
When attempting the fresh login, the ADFS authentication server screen pops up. The user enters the credential and gets redirected to the designated redirect URI.
However, on subsequent attempts the user is not asked for any credentials even after I cleared all the token data from Local Storage. The cookie for the document are also cleared.
Although, this seems like a desired behaviour I would still like to know how it happens. Does Cognito cache some kind of ID data somewhere. I tried searching for something like this but didn't find any related article.
"Does Cognito cache some kind of ID data somewhere"?
No, ADFS does.
There is a client-side cookie and a server-side cookie.
Let's say the ADFS timeout is set to 8 hours.
So you log in the first time, and cookies are created on both sides.
Now on the client-side, the access token expires (assuming OIDC) and the client sends a refresh token. ADFS checks its cookie has not expired and then sends a new access token.
As long as the ADFS side has not expired, you get SSO.
Just for completeness, when you log out, ADFS clears its cookie. When the client-side receives the logout response, it clears its cookie.
Now you have to re-authenticate.

How do I implement session authentication across microservices?

I'm working on a project for which I have planned the following architecture:
auth.example.com: Provides login, registration, and password-reset functionalities.
accounts.example.com: Allows users to update their account data.
example.com: Provides other services.
I have figured out the following solution for maintaining authentication across all domains:
Authenticate user on auth.example.com and set a cookie containing JWT token (signed token with shared key) which contains the user data and its domain is set to .example.com.
Once the user is authenticated, redirect them to example.com/dashboard and verify the JWT token present in the cookie. If the token is valid, present the service to the user else redirect to auth.example.com.
Now, I have the following doubts:
Suppose if a user updates his name on accounts.example.com, how do I make all other services use the updated user data?
If I want to ban a user or delete their account or terminate all active sessions, how would I let other services that the user shall not be authenticated?
Is there any better approach to solve this problem?
JWT tokens are generally stateful means they have everything to be authenticated, once issued they can be used and there is no way we can revoke them. However there are few approaches that we can use.
Normally we keep the life time (expiry) of token short (e.g. 15 mins) and refresh the access after X minutes using Refresh Token (Know the difference between Refresh and Access Token).
Say the token is about to get expired then we will re-issue the access token (refresh token will do that without user sign in again). Refresh tokens are long lived token and have to be handled carefully. If we have to revoke the access then we need to revoke Refresh token and after X mins user is not able to get access token since Refresh token is revoked already.
During the time when you revoked the refresh token , any access token issued is still valid until reaches its expiry. If you want to invalidate the token before that then you may have to blacklist the token and maintain the list of such tokens that will stop the user from login using that particular token.
I have found very nice explanation here Check Revoke Token
Club JWT token, protocols like oauth and openid and store the session in redis/memcache.
This redis/memcache will be single point of contact for all your microservices.
Say microservice m1, m2, ... are independent and using restapi gets connected to microservice called mR which checks the session in redis/memcache.

oAuth 2.0 - Acting on behalf of the user

I'm new to oAUth2 and I'm trying to get a few things straight.
I understand the basic principles involved with oAuth2 but I am not sure how to implement it in my situation.
I am writing an app that acts on behalf of the user to automate a manual process and perform some tasks(update/request status...etc). The API we are connecting to uses oAuth2 to grant our application permission. We plan on having the user grant our application permission when they create a new account with us.
I understand that the user will request an authentication code that is provided to our application. Then our application will use the authentication code to generate an access token.
We would like to do this only once. Then act as the user to send and receive notifications without having to have the user to log into the service with their credentials.
I am not sure how to implement this without having to store the user credentials to get an auth code since the auth code and auth tokens expire. I'm guessing that this is a common scenario.
What would I need to do to get what I want accomplished?
You can get a new AccessToken using a RefreshToken, if this is provided by the Authorization Server.
If it's not provided I would contact the Api provider, you should never store a users credentials. In fact if the OAuth protocol is well implemented as a client you should never be able to even get the client credentials. When the user has to login you should redirect the user to the Authorization Server, there the user should login and then the authorization token should be redirected to your application by the Authorization Server.
See also this explanation on Refresh Tokens from the OAuth 2.0 spec:
Refresh tokens are credentials used to obtain access tokens. Refresh
tokens are issued to the client by the authorization server and are
used to obtain a new access token when the current access token
becomes invalid or expires, or to obtain additional access tokens
with identical or narrower scope (access tokens may have a shorter
lifetime and fewer permissions than authorized by the resource
owner). Issuing a refresh token is optional at the discretion of the
authorization server. If the authorization server issues a refresh
token, it is included when issuing an access token
Note
If you request a new AccessToken using your RefreshToken and the response includes a new RefreshToken you should overwrite your currently saved RefreshToken. With other words, you should always use the latest RefresthToken you received.