I am using IBM Mobilefirst platform 8.0 at the moment.
Currently, I am facing a problem:
On my MFP, I have 1 security check to protect 1 adapter.
The flow is that:
login with the security check
can obtain access token (I call it TOKEN_1)
can request resource from adapter
logout
This step, I use the TOKEN_1 to request the resource from adapter and it returns 401 unauthorized (it's correct here)
login with the security check again
can obtain a new access token now (I call it TOKEN_2)
At this time, I can use both TOKEN_1 and TOKEN_2 to request the resource from the adapter and I think that it's not a good thing (just for my case and from my point of view)
I would think that the TOKEN_1 should not be valid anymore but only the TOKEN_2.
So, my question is that there is any way to invalidate forever an access token after we logout with MFP?
Thank you so much in advance.
You can manually clear out the access tokens in the mobile device using the API clearAccessToken.
You can invoke it before or after your logout call. This is to ensure all token related data held in-memory is cleared. This does not clear any token data you have recorded within in your code and stored.
Once you have logged out with WLAuthorizationManager.logout(securitycheck) , the next time you request a protected resource, MFP client SDK always obtains a new token.
Related
Using Java OAuth2 client library: scribe 1.2.0 (https://github.com/scribejava/scribejava)
I am able to get refresh token from the authorization code (i.e; by making POST call to https://accounts.google.com/o/oauth2/token with client_id, client_secret, code, scope, grant_type (authorization_code), redirect_uri parameters). And I have persisted the refresh token in DB.
And we support drive and calendar scopes => so, I do store two refresh token per user (email)
And then clients will be invoking API to get access token (then I am making POST call to https://accounts.google.com/o/oauth2/token with refresh_token, grant_type (refresh_token), client_id and client_secret). And the call is successful. i.e; happy normal path works.
But eventually getting new access token from refresh token is failing with invalid_grant error code (with Bad Request OR Token has been expired or revoked as errors) (like in 2 days or 3 days etc)
Please do note that the refresh token is not revoked or invalidated explicitly by user or code. Password is not changed. Code is not changed. Client ID and secrets didn't change. I am kind of lost.
Questions
Since refresh token supposed to be a long lasting token, why my application is not able to get new access token from refresh token? Its just failing in like in 2 to 3 days - and its happening regularly in stage and production environments.
Is storing two refresh tokens based on scope (drive and calendar) - per user (email) problem (i.e; as soon as second refresh token is issued the previous refresh token expire)? [Shouldn't be the case - I do know there are limitations per user and client, per user for all clients. But, 2 is too low to reach that limit.]
Answer
Finally was able to resolve it, please see the answer below comment(s) - its related to having two refresh tokens of same email for different scopes, and invalidating one of them.
Getting access token from Refresh token - PostMan
Getting refresh token from authorization code - PostMan
Relevent questions: Google token refresh returns "Token has been expired or revoked."
Since couple of days Refresh token has been automatically expired
Changed password
There are serval reasons why your refresh token maybe expiring. The first one we can lockout as the cause is the user changing their password if you are using a gmail scope and the user changes their password this will cause all outstanding refresh tokens to expire.
User revoked access
If the user revokes your access directly though their Google account this will also revoke your refresh token.
Application status.
Now is your application still in testing on Google cloud console? Have you moved it to published has it been though the verification process? If not then your refresh tokens will probably be expiring after about two weeks although the time frame may have changed as this seams to be something that Google has been working on for the last serval months and there is no official word on it.
Refresh access token gives refresh token.
Another cause which actually could be the case, when you refresh the access token does it return a new refresh token. sometimes I will do this. Always check that this is the same refresh token that you use before if note then its a new one and you should store the new one. See next point for more info on why.
Max number of outstanding refresh tokens.
When a user authorizes your application using offline access you are given a refresh token, if the user authorizes your application again you are given another refresh tokens. you can keep doing this up to fifty times and all fifty refresh tokens will continue to work. As soon as you go over the magic number of fifty then the first one that was created will be expired. This is why it is important to ensure that you are always storing the most recent refresh token for a user in your database.
Basically, if your app has multiple refresh tokens for the same user (Gmail) with different scopes, invalidating one of them will invalidate all the tokens.
that turned out to be the issue as we maintain different refresh tokens based on scopes (say drive, calendar, contacts etc)
I'm using Xero-Java and I'm trying to push invoices to Xero. The scopes I requested in the Ouath2 authorization were:
openid
email
profile
offline_access
accounting.settings
accounting.transactions
accounting.contacts
accounting.journals.read
accounting.reports.read
accounting.attachments
Invoking the AccountingApi.updateInvoice() method throws the error:
com.xero.api.XeroApiException: Unauthorized - check your scopes and confirm access to this resource
I was under the impression that the scope accounting.transactions would allow pushing Invoices to Xero. Where is my problem and how do I fix it?
Thanks.
Looking at some logs, it seems that your access token has expired. Access tokens only live for 30 minutes.
As you've used offline_access, you can acquire a new access token for the same user by using the refresh token provided during user authorisation with a refresh request as outlined in the Readme of the SDKs github repo.
You'll probably want to check token expiration prior to each call to the Xero API.
I follow the steps in the Spotify Web Api Tutorial using the authorization-code from the Spotify Accounts Authentication Examples. Everything is okey, I register an application with Spotify, authenticate a user and get authorization to access user data and when the page show me the user data the refresh token is different each time I authenticate myself. I think refresh token shuld not change.
The only modification I did in the example code was replace the client id, client secret and the redirect uri with the correct values from my application.
Any advices?
For the Authorisation Code Flow you just need to do that initial authentication you're already doing. It will always return a new refresh token however that token can be used over an over with 4. Requesting a refreshed access token; Spotify returns a new access token to your app from Authorisation Guide that will return you a new access token for subsequent calls and you won't need to do the Authentication Step you're doing multiple times just keep doing that one.
I have a mobile application that uses my Spring Boot backend for things like authentication and accessing data. A part of the Spring Boot application accesses data from a resource server using OAuth2. I stumbled across an oauth2 client library for Spring that does its magic and everything just works out of the box.
As I'm trying to figure out how this library does its work, I can't seem to find an answer to the way it handles refresh tokens. I'm aware that the oauth2client is bound to a session for each user but what happens when the session ends? Wouldn't the access and refresh tokens get lost?
I was looking for ways to persist the refresh token for each user in my database but I didn't find any support for that in the library. This leaves me wondering if I have to implement this myself or if there's even a need to do so.
Any advice is appreciated!
Basically OAuth2 architecture is used for 3rd-party authentication and authorization. In this mechanism the credentials remains secured and aren't passed on while everything works upon tokens! But you can use it to work implicitly for your own authentication too.
In your case first when you hit "/oauth/token"(default endpoint) along with the client-secret and client-Id and rest of the user credentials the algo checks for the user details in the DB and matches the secret and Id present in the header of the request. If everything goes fine it'll generate a bearer type - access and refresh token and will store these tokens in different collections in the database.This particular user is mapped to these tokens and can access /api's using them only.No user creds are required. You can use MongoTokenStore if you're using MongoDb for storing and accessing stored tokens.
Next you have to configure WebSecurity/AuthorizationServer/ResourceServer for checking endpoints and header tokens tokens, authentication and authorizaton of users and providing valid tokens access to the resource respectively.
Lastly when you have a valid access token and hit an api with a correct header request the server grants you permission to access the resource!
This is the basic functionality of the OAuth2.0.
Normally Access Tokens have a shorter lifetime while refresh tokens have comparitively larger lifetime. Once Access Token gets expired a new Access Token can be generated using the Refresh Tokens. If the Refresh Tokens gets expired then you have to hit the "/oauth/token" api again,complete the flow cycle and generate tokens again.After expiry when you hit an api with existing access token they are removed from the collection. This is the default architecture of this mechanism, rest you can make custom classes and modify its functionality according to your needs! This architecture is quite secure and is a good practise.
Screenshot Flow Diagram
Check this post from digitalocean.
Edits ----
Personally I used MongoDB where I made two collections -
AuthAccessTokens and AuthRefreshTokens namely where these two were
stored. Access Token object has an Id of associated RefreshToken
which helps to map these two together. Rest custom additional Info.
can also be added using TokenEnhancer. Therefore tokens will always
be present in the DB unless expired. And in layman's terms if you
are just focussing on Backend stuff you can always check for your
access tokens by hitting "/oauth/token" with correct user creds and
it will return the assigned token by fetching it from the DB, else
if you're developing full stack after generating the tokens on first
step just store them on client end either in browser's local storage
or app. And if you want to deliberately end the session like for
example in Logout just remove these tokens from their respective
collections.
I want to get users' access_token by using Google Drive SDK in JAVA.
I completed to get access_token when user log-in first time. But, I really want to direct-login. I know access_token be expired, so 'refreshToken' can be my solution. But refreshToken is always 'null'. How can I perform direct-login? Many advices welcome.
You need to separate "login" from "access drive". Once your application has an access token for a given user/scope, it can access Drive on behalf of the user. There are two (main) ways your application can obtain an access token.
It can request access which will involve the user being logged in to grant access.
In step 1, it can request "offline" access, in which case it will be given an access token and a refresh token. It can subsequently use the refresh token to request more access tokens without the user being present.
I suspect that you want to do option 2. This is described quite well at https://developers.google.com/accounts/docs/OAuth2WebServer#offline
If you have tried this and you having problems, please paste your code and the http trace so we can look at the problem with you.