Storing refresh tokenSee original GitHub issue
I managed to implement the authentication flow (while still waiting for https://github.com/microsoftgraph/msgraph-sdk-java-auth/issues/14) and now I wonder what I should store long-term so that the users do not have to re-authenticate once their session is gone. The refresh token alone is not enough, I guess, we also need the account, the scopes are good to remember too just like the expiry.
TokenCache is a candidate (why doesn’t
Serializable?) even though I’d prefer not to store some serialized 3rd party object in the DB that might change at any time. But the silent flow sample also uses the
IAuthenticationResult that’s held in the session. I might extract the account from the
IConfidentialClientApplication.tokenCache() only returns a
ITokenCache and not the
TokenCache so I’d have to blindly cast it.
tl;dr Before I stitch together a whacky solution - is there an official thing to store away? I’d like to actually use the refresh tokens long-term to not annoy the users with re-authentication. The most reliable and straight forward thing that comes to my mind without digging too deep is to code custom wrappers for
IAuthenticationResult to store them away.
- Created 3 years ago
- Comments:5 (2 by maintainers)
Top GitHub Comments
@Avery-Dunn thanks for the thorough reply! I missed the other constructor on SilentParameters. Now it’s down to using my own
I’ll open some issues in the msal4j repo.
Thanks again and have some nice holidays!
@black-snow For the accounts, it depends on how you’re using the cache
- If you’re storing a cache in each session and each session maps to one account (I think this how this sample does it), then you don’t need to provide the account to
SilentParametershas a builder for scopes+account as well as just scopes, and if not provided an account then it will still work if each cache has one account.
- If you’re storing multiple accounts in a cache, then you can just call the application’s
getAccounts()method, find the account you need from the returned set, and then do the silent calls with that account. If you’re loading up the client app and have a persistently stored cache, then you just need to set the cache when starting up the app like in this sample, after which you can call
getAccounts()to get them all from that cache
For the token cache, most of this was all designed before my time here, but I believe the reason that most of the internals of the token cache aren’t public is because they shouldn’t ever need to be adjusted manually, refreshing is taken care of by the library’s silent calls, and I think pretty much everything in the token cache is retrievable in some way:
- If you want the whole token cache just as a JSON-formatted String (for storing, parsing, etc.), you can get that through the client app’s AbstractClientApplicationBase.TokenCache.serialize()` method
- If you want all of the account objects, you can use
AbstractClientApplicationBase.getAccounts(), and an account should be in
AuthenticationResultobjects returned in every token request (both silent requests and specific flows)
- If you want all of the ID/access/refresh tokens, you can get it either from the
AuthenticationResultobject returned in the initial token request, or in the
AuthenticationResultobject returned when making a silent token request (this will have either the cached tokens, or the refreshed tokens if the originals expired)