Which Version of MSAL are you using ?
MSAL 4.7 .1
Platform
net.45 framework
What authentication flow has the issue?
Other? - please describe;
Is this a new or existing app?
c. This is a new app or experiment
Repro
public static async Task<string> GetToken(string User, string Pass)
{
string[] scopes = new string[] { "user.read" };
string token = "";
IPublicClientApplication app;
app = PublicClientApplicationBuilder.Create(ConfigurationManager.AppSettings["clientId"]).WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs).WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient").Build();
AuthenticationResult result = null;
var accounts = await app.GetAccountsAsync();
try
{
result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync();
Console.WriteLine("Using cached token");
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
if (result == null)
try
{
var securePassword = new SecureString();
foreach (char c in Pass) // you should fetch the password
securePassword.AppendChar(c); // keystroke by keystroke
result = await app.AcquireTokenByUsernamePassword(scopes, User, securePassword).ExecuteAsync();
Console.WriteLine("Using provided credentials to gather a token");
}
catch (MsalException)
{
Console.WriteLine("Login Failed");
}
if (result == null)
{
try
{
result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
}
catch (MsalException)
{
///
}
}
token= result.AccessToken;
return token;
Expected behavior
Token to be cached after first login, and then used instead of having to use interactive or proving creds.
Actual behavior
Token is never pulled from cache or is ever stored.
Additional context/ Logs / Screenshots
Error is:
MSAL.Desktop.4.7.1.0.MsalUiRequiredException:
ErrorCode: user_null
Microsoft.Identity.Client.MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call.
at Microsoft.Identity.Client.AcquireTokenSilentParameterBuilder.Validate()
at Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder`1.ValidateAndCalculateApiId()
at Microsoft.Identity.Client.AbstractClientAppBaseAcquireTokenParameterBuilder`1.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.AbstractAcquireTokenParameterBuilder`1.ExecuteAsync()
at SharpZure.SharpZure.<GetToken>d__3.MoveNext() in C:\Users\Ryan\OneDrive - Specter Ops\Tools\SharpZure\Program.cs:line 121
StatusCode: 0
ResponseBody:
Headers:
I assume this is because you have not setup a token cache serialization strategy. By default, MSAL caches the tokens in memory only - see https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/token-cache-serialization
The link above shows you how to serialize on Windows. If you are looking for a cross-platform serialization strategy, we've written one here: https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet#msal-extension-for-public-client-applications
PS: I'm glad you're on the latest MSAL now :)
Ahhhh that was it, I apologize for missing that docs, I greatly appreciate the help!
This is fine @hausec , happy to help. And you've seen that we've opened some bugs / feature improvements based on these questions that you have, so this is quite useful.