Cognito User Pool - Are refresh tokens tied to client ID? - amazon-cognito

While doing some cross-team work the other day attempting to get an API endpoint in place to facilitate the use of refresh tokens, I was a bit stumped as to why I was getting an "Invalid Refresh Token" error back when I would try the InitiateAuth or AdminInitiateAuth actions when attempting to use the REFRESH_TOKEN or REFRESH_TOKEN_AUTH flows.
In the .NET API we are transitioning over to Cognito, I was using one Client ID. We were also using another client ID for a starter project that we could hit to get JWTs back. From what I can tell, the Client ID is tied to the refresh token, which is why I was getting the invalid token error.
Can anyone confirm that has a bit more experience?

You are correct, it is tied to a client id.
Source: I work on the Cognito team.

Related

Persisting a login with the Slack API

I currently have this flow but I am unsure of the architecture going forward.
On my page, the user gets sent to the Slack OAuth API where they confirm scopes
User gets redirected back to my page with a one time code
Client sends a request to the server with the code
The server sends a request to Slack with the code, exchanging it for an access token
If the code and token are OK, it creates a new user in MongoDB
I made a flowchart to illustrate:
I would like the user to not have to authorize the scopes every time they want to access the service, and even if they did, how would I keep the token around in a secure manner to make requests? Would I have to create my own token authentication with login and password, or is there a better way? Should I persist this token on the client somehow and have the users be logged in that way? If so, what is the best way to do that?
Slack token generation must be one time activity per user.
When creating user in MongoDB, you should also store the generated token securely.
For later use, your application should use the stored token for any slack interactions, given that you have authenticated the user whose token you'll be using.

Retrieve user access TOKEN from WSO2 Api Manager

I have a problem with retrieving the end-user access token from wso2, I need it to invoke the API that retrieves the list of all applications in the Wso2 Api Manager Store. I did a research on this site:
https://docs.wso2.com/display/AM210/apidocs/store/#!/operations#ApplicationCollection#applicationsGet,
but I don't know how I can generate user token (not application token).
On the other side I found the temporary solution, that returns a list of all applications invoking the API login, and then API that returns the app list found on this link: https://docs.wso2.com/display/AM210/Store+APIs, but it shows me only how to do it with a session authentication, NOT with JWT token auth.
thanks in advance.
Please follow the getting started guide[1]. For a token generation, you need client id and secret. To get that you need to register an application.
[1] - https://docs.wso2.com/display/AM210/apidocs/store/#guide

Authentication flow for temporary credentials in the browser

I'm trying to wrap my head around a specific proprietary authentication flow used by one of our customers, and how to implement it in IdentityServer4.
We're developing an SPA with some microservices as backend and do all our authentication/authorization with IdentityServer4. The standard workflow for the SPA is (as expected, I guess) the implicit flow using oidc-client-js (for now).
Now the problem: one of our customers has something like a homebrew SSO solution dating way back. Users basically authenticate at a central portal and get a link to the application with a token attached. This token is valid for a few minutes and contains the temporary user credentials, I need to somehow authenticate at our IdentityServer.
My first attempt was the client credentials flow. Doesn't work, as the client cannot refresh its access token later, once the initial credential token ran out (the client does not and cannot have access to permanent credentials.) My current approach would be to kind of "hijack" the implicit flow, by authenticating with the given temporary credentials and from there on out use the normal refresh cycle without further need for any credentials.
Is this a valid approach or am I completely on the wrong track? If it's valid: how do I get IdentityServer4 to do my bidding? I cannot use IResourceOwnerPasswordValidator, because that would require the client credentials flow (I think?). Is an IExtensionGrantValidator the way to go? (If so: any ideas, how to convince oidc-client-js to use a custom grant?)
Thanks for your help.
Regards,
Markus

What to do after getting oauth2 token?

I'm trying to implement a "Sign in with ..." authentication system.
I've read several posts and articles on oauth2. Everyone that I've read stops the discussion or tutorial at getting the access token and possibly logging in the user for that session.
I understand that and can implement that part. Here's what I don't get:
When the user leaves the site and doesn't come back for a week, but they're still logged into the client, how do I log them back into my app? I know you save the access token to the DB, but how do you use that to log them back in?
If they're logged out of the client, how do you redirect them to the sign in page of the client. It seems that every time I try to log back in I'm asked to allow or deny the app again. I know that isn't standard, so how do I fix that? What do I send the client so that it knows that the user has already authorized the app?
I don't need a code sample unless someone knows of an article, what I would really like is just a high level overview of what to do with the access token after I have received and saved it.
Thanks!
EDIT:
I understand that OAuth2 isn't an authorization system in itself, but everyone and their dog has a "Login with..." option. And in order to do this it's necessary to use OAuth2 (or some form of API identifier). That's what I'm trying to do.
Does the following sound like the correct flow:
Get temporary code from auth server
Trade that for access token
Get user data from auth server and do whatever you want with it (probably save to a DB).
Log the user in, saving the refresh token as well.
Set an identifier in a cookie for the user (the access token)
When user comes back, identify them via the cookie token.
Try to make a call to the api and see if the access token is still valid.
If access token is still valid, great!
If access token isn't valid, then get a new one via the refresh token.
Is that the basic gist of using OAuth2 to help authenticate a user?
First of all, OAuth2 is not an authentication protocol. The issued access token does not sign you in, but allows you to call a web service (API).
OpenID Connect is an authentication protocol built on top of OAuth2. It allows you to get back an id_token from the authorization server that identifies the user. If you safe the token (or the info in it) in for example a cookie, you can establish a authenticated session for the user.
You also do not store access tokens in a database. Access tokens are short-lived and storing them on the server side serves no purpose.
You do store the refresh token in a database. When the client (app requesting the token) is confidential (can keep a secret), a refresh token may be issued. The client can use this refresh token to request a new access token for the API when the old token expires. This is what will surely happen when the user did not visit the app for a week.
This is what I do when using OAuth 2 tokens:
1.) You should store the access token in the local storage of your client. So once you stored it you can use it for every request you make like adding it to the Authorization Header "Bearer " + accessToken;
Don't forget to clear the local storage of your client when they logout.
2.) Basically if you send a request to the API and it returns "HTTP Error 401 Unauthorized" (Status 401) then you know that you should immediately re-direct the user to the login page because he/she is not authorized.
Well, if you are using role-based authorization then there's a possibility that the user is logged-in but is not authorized. This scenario should be handled by you. Only display actions on the UI corresponding to the authorization level of the user.
Hope this helps.

How to make Google sign-in token valid for longer than 1 hour?

I have implemented google sign-in successfully.
I am able to authenticate user and in response I receive token. However the token expires in 1 hour.
expires_in: "3600"
I tried searching in the docs - https://developers.google.com/identity/sign-in/web/reference - but cannot find a paramenter to extend the lifespan of the token.
What I'm actually trying to do?
https://developers.google.com/identity/sign-in/web/backend-auth
after a user successfully signs in, send the user's ID token to your server using HTTPS
I'm sending token with each request to the server:
endpoint/get?access_token=" + access_token
And then on the server I'm calling https://www.googleapis.com/oauth2/v3/tokeninfo
So I have a token, every request is authenticated, but after 1 hour of working the tokeninfo method returns false and I need to re-authenticate the user.
In my code I circumvented that by storing all the historical access_tokens and if client uses old token I check against historical data and manually issue new token using refresh_token (one of my permissions is to grant offline access)
So yes, I'd be very interested to know:
How to expand lifespan of the access_token?
OR
Given the limited lifespan how to ensure requests are authenticated on the backend?
As #DaImTo noted, you can't extend the life of an access_token. You can get a new one using a refresh_token, but often if you're trying to do this client side and have a server, you should re-think your approach.
It sounds like there are two "authentications" that you're doing here - the client authenticating against the server, and the server authenticating against the Google service. Right now, the server should be holding onto the refresh token - so it can always re-authenticate against Google. It sounds like you're wrestling with how to authenticate your client against the server after the auth_token timeout.
In general, the client shouldn't send the access_token to the server, nor the refresh_token. What it does is during the first sign-in, the client gets a one-time code (from Google) which it hands to the server. The server uses this to talk to Google and get the access_token and refresh_token, confirming the user has authenticated themselves, and then sends something (usually a cookie) back to the client saying "ok, I've authenticated you. Here is how you keep authenticating yourself for the rest of our conversation."
That later action is pretty standard and is unrelated to oauth itself. The client and server then communicate as they always do - no oauth stuff is exchanged at all, you're relying on the cookie (or equivalent) to keep up the client-server authentication. The server continues to use the auth token and refresh token to talk to Google.
https://developers.google.com/identity/sign-in/web/server-side-flow I think is the best guide to this at the moment. Or at least it is the best one I can find at the moment. It has a good diagram, at least.
The key point is that you're exchanging the brilliantly named "code" with the server (what I was calling the "one-time code"). Once you have done that, the server authenticates you with Google - and it then has the access/refresh tokens and you communicate with the server without having to pass those.
Access tokens are short lived and only last for one hour this is not something you can extend.
What you need to do is take the refresh token and get a new access token.
example:
You take the refresh_token that you got from your initial request and HTTP Post it to: Note: grant_type=refresh_token
https://accounts.google.com/o/oauth2/token
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&refresh_token=1/ffYmfI0sjR54Ft9oupubLzrJhD1hZS5tWQcyAvNECCA&grant_type=refresh_token
response
{
"access_token" : "ya29.1.AADtN_XK16As2ZHlScqOxGtntIlevNcasMSPwGiE3pe5ANZfrmJTcsI3ZtAjv4sDrPDRnQ",
"token_type" : "Bearer",
"expires_in" : 3600
}