Xamarin.Auth vs MSAL: Choosing Silent Token Acquisition for Expired Refresh Tokens
0 reputation · 26 Aug 2024, 01:45 UTC
0 reputation · 26 Aug 2024, 01:45 UTC
In a Xamarin.Forms app, the objective is to request only the scopes required for a feature, store the resulting access and refresh tokens securely, and refresh the access token silently when it expires. The design must also handle the case where the refresh token itself becomes invalid (revoked or expired).
Both Xamarin.Auth and Microsoft.Identity.Client (MSAL) rely on iOS Keychain and Android Keystore for token persistence. The behavior of silent token acquisition differs across these platforms, especially when the underlying refresh token is no longer valid.
It is unclear whether MSAL will silently fail on a revoked refresh token on Android, forcing an interactive prompt, whereas Xamarin.Auth may provide a more deterministic fallback path. The choice impacts user experience and compliance with least‑privilege principles.
31775 reputation · 26 Aug 2024, 02:13 UTC
MSAL does **not** silently fail when the stored refresh token is revoked or expired on Android (or iOS). A call to AcquireTokenSilent throws MsalUiRequiredException (or a MsalServiceException with error interaction_required). The app can catch this exception and then invoke an interactive login flow.
try
{
var result = await app.AcquireTokenSilent(scopes, account)
.ExecuteAsync();
// use result.AccessToken
}
catch (MsalUiRequiredException ex)
{
// refresh token is invalid → start interactive auth
var interactiveResult = await app.AcquireTokenInteractive(scopes)
.WithAccount(account)
.ExecuteAsync();
}
For Xamarin.Auth, a silent refresh (RefreshTokenAsync) throws an AuthenticationException whose message typically contains invalid_grant. You must catch this exception and then launch the authenticator’s UI to obtain a new token pair.
try
{
var newToken = await authenticator.RefreshTokenAsync(params, cancellationToken);
}
catch (AuthenticationException ex) when (ex.Message.Contains("invalid_grant"))
{
// start interactive login (e.g., presenter.Login())
await presenter.LoginAsync();
}
Both libraries store tokens in the platform‑specific secure storage (iOS Keychain, Android Keystore/AccountManager or EncryptedSharedPreferences). The storage mechanism does **not** change how revocation is detected—the authority’s token response determines validity. However, Android’s hardware‑backed Keystore offers stronger protection against token extraction than software‑only storage, while iOS Keychain provides comparable hardware‑backed security.
To be certain that observed silent failures are due to token revocation and not storage‑related issues, confirm which Android storage you are using for MSAL/Xamarin.Auth (Keystore vs AccountManager). If you are using AccountManager, clearing the account or disabling the app can produce similar silent failures unrelated to token status.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.