我有一个条件设置为,如果有缓存的令牌,它将使用该令牌,否则它将寻找传入的凭据或提示输入凭据。即使通过AcquireTokenInteractive()输入了一次凭据并再次运行该程序后,它仍然会提示您输入凭据。如果我只有AcquireTokenSilent(),则会因为token
变量而导致引用错误,因为没有任何内容传递给它。它要么没有缓存我的令牌,要么没有正确获取我的缓存令牌,但是我不确定如何解决这两个问题。根据MSDocs https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens,它应该自动进行缓存。
暂时,我出于故障排除的目的将AcquireTokenByUsernamePassword()注释掉。
static async Task<GraphServiceClient> Auth()
{
string[] scopes = new string[] { "user.read" };
string token = null;
IPublicClientApplication app;
app = PublicClientApplicationBuilder.Create(ConfigurationManager.AppSettings["clientId"])
.Build();
AuthenticationResult result = null;
var accounts = await app.GetAccountsAsync();
if (accounts.Any())
{
result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
.ExecuteAsync();
}
else
{
try
{
///var securePassword = new SecureString();
///foreach (char c in "dummy") // you should fetch the password
/// securePassword.AppendChar(c); // keystroke by keystroke
/// result = await app.AcquireTokenByUsernamePassword(scopes,"[email protected]",securePassword).ExecuteAsync();
}
catch (MsalException)
{
///
}
try
{
result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
}
catch (MsalException)
{
///
}
}
token = result.AccessToken;
// Use the token
GraphServiceClient graphClient = new GraphServiceClient(
"https://graph.microsoft.com/v1.0",
new DelegateAuthenticationProvider(
async (requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token);
}));
return graphClient;
}
是的,你是对的。 SDK将自动进行缓存。我通过创建控制台应用程序对其进行了测试:
class Program
{
static void Main(string[] args)
{
string flag = "Y";
IPublicClientApplication app = PublicClientApplicationBuilder.Create("60ef0838-f145-4f00-b7ba-a5af7f31cc3c").Build();
string[] scopes = new string[] { "api://4a673722-5437-4663-bba7-5f49372e06ba/Group.All","openid" };
do
{
List<IAccount> list = app.GetAccountsAsync().GetAwaiter().GetResult().ToList();
Console.WriteLine("Checking cache");
if (list.Count > 0)
{
Console.WriteLine($"Find {list.Count}");
list.ForEach(_ =>
{
Console.WriteLine($"Acquire a new token for {_.Username}");
AuthenticationResult result = app.AcquireTokenSilent(scopes, _).WithForceRefresh(true).WithAuthority("https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/").ExecuteAsync().Result;
Console.WriteLine($"New token -> {result.AccessToken}");
});
}
else
{
Console.WriteLine("No cache");
try
{
var securePassword = new SecureString();
// Test AcquireTokenByUsernamePassword
foreach (char c in "**********") securePassword.AppendChar(c);
AuthenticationResult result = app.AcquireTokenByUsernamePassword(scopes, "[email protected]", securePassword).WithAuthority("https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/").ExecuteAsync().GetAwaiter().GetResult();
// Test AcquireTokenInteractive
//AuthenticationResult result = app.AcquireTokenInteractive(scopes).WithAuthority("https://login.microsoftonline.com/e4c9ab4e-bd27-40d5-8459-230ba2a757fb/").ExecuteAsync().Result;
Console.WriteLine(result.Account.Username + " -> " + result.AccessToken);
}
catch (Exception e)
{
Console.Error.WriteLine(e.Message);
Console.Error.WriteLine(e.StackTrace);
}
}
Console.Write("Continue? Y/N:");
flag = Console.ReadLine();
} while (flag.Trim().ToUpper().Equals("Y"));
Console.ReadLine();
}
}
结果: