Background:
I have a requirement where I need to allow the refresh token live for a really long time for some types of user, but I want to limit it (expire it) for other users.
Both sets of users have to be in the same Cognito user-pool.
My first thought was to check how long the users have been logged-in if they are the type of user I want to limit and call global sign-out to force those users to re-authenticate, but I cannot find any API that will tell me how long a user has been logged in.
As an important side note, since I am using Cognito with Amplify + Appsync, the refresh token is used to obtain new session tokens until the refresh token expires.
Question:
Is there a way in Amplify or Cognito APIs to find out how a user has been logged in in that particular device?
Cognito has a feature that remembers the user's device and records the date in which the device was last authenticated.
Ref: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-device-tracking.html
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetDevice.html
Related
I have developed an IOS app, and I am using cognito for authentication. And the refresh token's expiry time is 1 year. But unfortunately we need all the users to re-login in app and we need to forcefully logout(revoke refresh token) every user from cognito, not only one or two users but all users form all devices.
I have researched a little bit and find that this can be done by revoking refresh token(of single user) but I can't find a solution where we can logout all users from all devices.
There is currently no such option to revoke all existing tokens.
All you can do is to iterate over each and every user and revoke tokens using the AdminUserGlobalSignOut API. You only need a username and a user pool ID to do it.
We are developing a web application in AWS which stores its users in Cognito. As part of this, we are required to have an integration with an existing desktop application, where the administrator of a client can create a read-only user for the website for data sent from the desktop app.
Because of this read-only user requirement, there has to be a user associated with the authentication for each instance of the desktop app installation. This is no problem, as we are happy that all local users of the desktop application have their data logged to the same place in the web application. The tricky part is that we are not able to have the username and password as common knowledge for the end-users of the desktop app.
It has been suggested that we could use token-based access to allow the desktop app to access our API, but these are all time limited and we would not be able to have the user re-authenticate each day. However, another suggestion is to create our own "key" which contains the username and password of the Cognito user in such a way that the application will be able to use it, such as encrypting the username and password with the decryption key available to the desktop app so that it can authenticate as that user itself without the end users having access to the account details.
I would like to know if there is currently any best practice way of handling a requirement like this that is better than what we currently have available.
To summarise:
We have an AWS API with Cognito Authentication
We have a desktop application which needs to access the API
We cannot have users know the details of the account being used to access the API
We need a way to provide a key that will allow the desktop application to authenticate itself against the API in such a way that the token will not need to be refreshed over time
Thanks for any help.
Unfortunately this requirement:
"We need a way to provide a key that will allow the desktop application to authenticate itself against the API in such a way that the token will not need to be refreshed over time"
is not going to be possible with Cognito. Assuming you are using Cognito user pools, the id and access tokens obtained on authentication are only valid for 1 hour, then they have to be refreshed using the refresh token. The refresh token can be configured to be valid for a really long time (years even) so you could setup a flow where:
The app authenticates itself against Cognito once
Gets a refresh token that is valid for a really long time
Throws away the original encrypted username/password
Uses the refresh token to get a new id/access token every hour
You would have to store the refresh token on the client somewhere though. And probably have a support mechanism where this process could be restarted on the client in case the refresh token is lost.
If you are using Cognito user pools, you are going to have to do token refreshes. Same is true if you are using Cognito identity pools - the AWS credentials provided by the identity pool are only valid for 1 hour, then they have to be refreshed.
I am trying to use AWS Cognito user pools with Cognito federation as auth for my APIs on api-gateway. I got the authentication & authorization part (using roles) to work, but now stuck on how to revoke access. After login & getting the federated identity, I deleted the identity from identity browser (console) & deleted the user from cognito user pool. But that does not invalidate access using the earlier generated tokens, till they expire (which is a minimum of 1 hour).
I also tried setting ServerSideTokenCheck to true, but that doesn't work either. The only way to "revoke" access seems to be this. But this does not work for us as our use case assigns roles to a group. I cannot have groups of users lose access to revoke/deny access to one user.
Is there anything I have missed to get this done? I cannot fathom an auth service which does not give me easy way to revoke access to user.
This is a common case with stateless JWT tokens issued with Cognito for authentication.
Once a user got hold of a token which valid for 1 hour, the token itself acts as the proof for authentication. The token is signed and issued by AWS and for validation it only requires to do a signature verification using a publickey.
The approach you can handle this is at the authorization layer in your application where you can check either the user is active/deactive in your database after the user successfully authenticates. You can further delete the user from Cognito where he is not able to login back again.
I see what you are saying and as the other answer explained when the token is issued, the user can use the token until its expiry date. A solution to your problem can be handled two ways:
Cognito way: For this, you make two calls to Cognito, first if the user is enabled, second if so, authenticate its token.
DB way: You have a DB, which act as a "black list" holder, so when you want to disbale the user, the app, adds the username of the user to the DB. Therefore, when the user wants to authenticate, you first check with the DB (if the user is enabled), then check its cookie for authentication/authorization.
Note: If your user base is small, you could go the Cognito way, however there is a limit to Cognito calls, if you have a large user base; you should consider the second approach.
I want to add to the token's payload a specific attribute. This attribute can be changed rarely (once per month), however I would like that the tokens would be updated immediately after this change.
WORKFLOW
In web/mobile app, user opens a profile view and changes attribute X. The current value of this attribute is also stored in ID token. So when user submit edits, the new value of X should be saved on the backend and should replace the old value in ID token. It is important, because attribute X determines whether user can or cannot do specific things in app.
What does Cognito do when payload's attribute change? It sends new version of JWT ID token in the next request?
Should I use refresh token? Or force to sign-out and sign-in user?
Refresh token will be more appropriate in this usecase. Currently, refresh token flow is not exposed in the high level android SDK for user pools because it is done behind the scene by the SDK. For now, you might have to call the refresh token from low level SDK to get around this.
(I am a developer from Amazon Cognito team, we will take this as a feature request to allow this from our high level SDKs.)
I'm planning out adding Facebook integration to a web app I'm working on. For the most part, it's proceeding smoothly, but I am confused on the proper way to handle the OAuth token.
The sequence of events presented by Facebook here is:
Ask the user to authorize your application, which sends them to a Facebook window.
This will return an Authorization Code generated by Facebook
You then hit https://graph.facebook.com/oauth/access_token with your Authorization Code, which will give you a time-limited OAuth token.
Using the OAuth token, you can make requests to access the user's Facebook profile.
Facebook's documentation has the following to say about token expiration:
In addition to the access token (the access_token parameter), the response contains the number of seconds until the token expires (the expires parameter). Once the token expires, you will need to re-run the steps above to generate a new code and access_token, although if the user has already authorized your app, they will not be prompted to do so again. If your app needs an access token with an infinite expiry time (perhaps to take actions on the user's behalf after they are not using your app), you can request the offline_access permission.
When they say to re-run the steps above, what steps need to be re-run to get a new OAuth token? What data (Facebook UID, Authorization Code, OAuth token) does it make sense to save to my local database?
I would like to be able to have the user continue to interact with my site, and in response to certain user actions, I would like to be able to prompt to user if they want to post something to their Facebook wall.
The access token is time and session based and is unnecessary data to store and have no use after the user have closed the session.
The facebook uid is the only thing you need to identify the user.
Since the Facebook API sometimes is horrible slow you could store the username aswell.
But for identification, all you need is the uid.
The documentation that facebook provides has been updated since you asked this question. https://developers.facebook.com/docs/authentication/.