Closed lx223 closed 11 months ago
Hello @lx223 : MSAL was designed to try to minimize how much you need to worry about refresh tokens, so we don't expose them.
However, if you need to persist the token cache we do expose the TokenCache object that each client application has, and you can serialize it whenever you need to persist it:
ConfidentialClientApplication clientApp = ... ; // Or PublicClientApplication
// ...other code
String cacheSnapshot = clientApp.tokenCache.serialize(); // JSON-formatted
What type of application do you have @lx223 ? And what MSAL API do you call ? Is it a web service calling another web service with AcquireTokenForClient? Or is a user involved?
@Avery-Dunn thanks for the info! Will give it a try. But if my use case makes sense it would be good to expose it rather than having to grab from json.
@bgavrilMS we have a web/vr app with MS SSO integration. take the web flow for example, user authorise a login via SSO, the web app sends the necessary info to the server and the server exchanges/validates using the lib and issues an app token to the web app. We would like to periodically check if the refresh token has been revoked from the identity provider side to revoke the app token on our side. Do you have recommendations on how to achieve this?
@lx223 - if I understand correctly, you have a web app that calls a web api? Do you own both components or just the web app?
What MSAL APIs do you call on the web app?
I've just got to this as well,
I'm in the process of putting MSAL app together for the first time and have found this part particularly confusing.
I need to persist the refresh token. The Oauth spec says we get both an access and a refresh token but I could not find anyway of obtaining it. It was not clear by the API that I need to provide a custom TokenCacheAspect to implement my persistence. Plus I believe that is the full cache making the exchange inefficient.
I have a standard Oauth interface where I need to implement the refreshTokens method to renew the access token and provide another set. This keeps the app consistent across all Oauth compliant interfaces. So I'm keen to understand how to achieve it using MSAL.
I saw one method in another post, https://github.com/AzureAD/microsoft-authentication-library-for-java/issues/228 But... reflection.....
I note there it was for security consideration, perhaps a method on the IAuthentiionResult, getRefreshTokenInsuecure()
Hello @HaydenDekker : As I said in my earlier comment here, every PublicClientApplication/ConfidentialClientApplication object you make has a tokenCache
field that has a serialize
method, and by default this will return a JSON-formatted string which will have all of the access/ID/refresh tokens retrieved by that ClientAppliction. You can persist this string however you want, and feed it back into a new ClientApplication object to populate a new cache with those tokens: https://learn.microsoft.com/en-us/entra/msal/java/advanced/msal-java-token-cache-serialization
You shouldn't need to handle refresh tokens individually: as long as you maintain the PublicClientApplication or ConfidentialClientApplication throughout the lifetime of your application then the acquireTokenSilently
call will automatically use them to get new tokens, and if you need to maintain the cache through any sort of app shutdown then you can persist that string and load it back into the new PublicClientApplication/ConfidentialClientApplication when your app starts up.
Thankyou, yes I've set that up. And I used the getAccounts() to find the account that matches my domain account requiring refresh in order to call that and keep msal separate from the application. Works well. Appreciate your help.
@HaydenDekker : Happy to help!
Closing due to inactivity from the original asker. If you're still having issues or have related questions, feel free to reopen this thread or start a new one.
Jumping in with another question. I noticed for the .NET implementation you allow persistent cache (source:
If perf is an issue, we should come up with a 2-layer cache: memory cache (L1) and persistent cache (L2). This is what we have in .NET for confidential client. For public client a disk access is very fast, I am not aware of perf considerations. So MSAL should always load from the cache and it's the cache's responsibility to be "fast". https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/5502)
Also, for the Java library, you allow persistent cache configuration for PublicClientApplication
. However, for ConfidentialClientApplication
there is no way to configure persistency, everything is in memory. Is that true? Are there any plans to have persistency for this one too in the near future @bgavrilMS ? It would spare users from implementing it themselves.
Hi @andra-popa - PublicClientApplication can make use of a persistence cache with the same semantics as MSAL.NET - see https://github.com/AzureAD/microsoft-authentication-extensions-for-java
For ConfidentialClientApplication
- web site, web api, service to service - all MSALs expose cache extensibility options, to allow app developers to define their own semantics. The more mature apps use a distributed cache like Redis to store token caches.
We recommend to always have at least a memory cache. Here is an implementation using Google Guava's memory cache that also has eviction https://github.com/Azure-Samples/ms-identity-msal-java-samples/tree/main/1-server-side/msal-client-credential-secret-high-availability
A few more recommendations:
Thank you for the help! I think we can use redis
Sure. Please don't hesitate to open new issues on this topic, even for questions and to include more details on the scenario you have. Our current samples are here https://github.com/Azure-Samples/ms-identity-msal-java-samples, will schedule some work if we have gaps.
@bgavrilMS I've encountered an issue while implementing our own token cache persistency: to call acquireTokenSilently
, we need to store the account object returned during the initial auth token request. Does that mean we have to implement our own serialiser to store the object somewhere? or is there a better solution?
We noticed the interface extends something called Serializable:
public interface IAccount extends Serializable { ...
but I don't see any serialising methods exposed
Hi @andra-popa - do you mind opening a new issue, as this one is closed and it's about something else. And pls describe in more detail the type of app you have etc.
It seems like there is currently no way via the library to retrieve the refresh token for persistence. Is there a reason for that and could it be added? The use case for me is to do periodic refresh using the refresh token to make sure the token isn't revoked by the identity provider with microsoft SSO. I am aware of the silent flow but that won't survive through server restarts.