MSAL 未将令牌存储在缓存中
MSAL not storing token in cache
这是代码:
using Microsoft.Identity.Client;
var scopes = new string[] { "user.read" };
var clientId = "4a1aa1d5-c567-49d0-ad0b-cd957a47f842";
var tenant = "common";
var authority = "https://login.microsoftonline.com/" + tenant;
IPublicClientApplication publicClientApp;
AuthenticationResult authResult;
publicClientApp = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(authority)
.WithRedirectUri("http://localhost:8080")
.Build();
var accounts = await publicClientApp
.GetAccountsAsync()
.ConfigureAwait(false);
IAccount? firstAccount = accounts.FirstOrDefault();
authResult = await publicClientApp
.AcquireTokenInteractive(new string[] { "user.read" })
.ExecuteAsync()
.ConfigureAwait(false);
authResult = await publicClientApp
.AcquireTokenSilent(new string[] { "user.read" }, firstAccount)
.ExecuteAsync();
这是抛出的异常:
Unhandled exception. MSAL.NetCore.4.44.0.0.MsalUiRequiredException:
ErrorCode: user_null
Microsoft.Identity.Client.MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call.
at Microsoft.Identity.Client.Internal.Requests.Silent.SilentRequest.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.Silent.SilentRequest.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.ApiConfig.Executors.ClientApplicationBaseExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenSilentParameters silentParameters, CancellationToken cancellationToken)
at Program.<Main>$(String[] args) in /home/adrian/temp/microsoft-identity-platform/simpler-version-public/Program.cs:line 25
at Program.<Main>(String[] args)
StatusCode: 0
ResponseBody:
Headers:
csproj 文件:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>simpler_version_public</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Identity.Client" Version="4.44.0" />
</ItemGroup>
</Project>
我的理解是调用AcquireTokenInteractive()
应该自动将token存入缓存,AcquireTokenSilent()
从缓存中获取token。那为什么我会收到错误消息?我在WSL中运行这段代码,dotnet --version
returns6.0.300
.
您在 AcquireTokenInteractive
之前调用 GetAccountsAsync
,但 return 没有任何帐户。没有帐户传递给 AcquireTokenSilent
,并且此方法不知道应该为哪个帐户获取访问令牌。
调用AcquireTokenInteractive
后需要调用GetAccountsAsync
。在这种情况下,它将 return 帐户和 AcquireTokenSilent
将从指定帐户的缓存中获取令牌。
authResult = await publicClientApp
.AcquireTokenInteractive(new string[] { "user.read" })
.ExecuteAsync()
.ConfigureAwait(false);
var accounts = await publicClientApp
.GetAccountsAsync()
.ConfigureAwait(false);
IAccount? firstAccount = accounts.FirstOrDefault();
authResult = await publicClientApp
.AcquireTokenSilent(new string[] { "user.read" }, firstAccount)
.ExecuteAsync();
根据 Microsoft 在 Github 存储库中提供的示例,您只需使用 app.AddInMemoryTokenCache()
with ConfidentialClientApplicationBuilder
, and new StorageCreationPropertiesBuilder(...).WithLinuxKeyring(...)
和 PublicClientApplicationBuilder
。
这是代码:
using Microsoft.Identity.Client;
var scopes = new string[] { "user.read" };
var clientId = "4a1aa1d5-c567-49d0-ad0b-cd957a47f842";
var tenant = "common";
var authority = "https://login.microsoftonline.com/" + tenant;
IPublicClientApplication publicClientApp;
AuthenticationResult authResult;
publicClientApp = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(authority)
.WithRedirectUri("http://localhost:8080")
.Build();
var accounts = await publicClientApp
.GetAccountsAsync()
.ConfigureAwait(false);
IAccount? firstAccount = accounts.FirstOrDefault();
authResult = await publicClientApp
.AcquireTokenInteractive(new string[] { "user.read" })
.ExecuteAsync()
.ConfigureAwait(false);
authResult = await publicClientApp
.AcquireTokenSilent(new string[] { "user.read" }, firstAccount)
.ExecuteAsync();
这是抛出的异常:
Unhandled exception. MSAL.NetCore.4.44.0.0.MsalUiRequiredException:
ErrorCode: user_null
Microsoft.Identity.Client.MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call.
at Microsoft.Identity.Client.Internal.Requests.Silent.SilentRequest.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.Silent.SilentRequest.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.ApiConfig.Executors.ClientApplicationBaseExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenSilentParameters silentParameters, CancellationToken cancellationToken)
at Program.<Main>$(String[] args) in /home/adrian/temp/microsoft-identity-platform/simpler-version-public/Program.cs:line 25
at Program.<Main>(String[] args)
StatusCode: 0
ResponseBody:
Headers:
csproj 文件:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>simpler_version_public</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Identity.Client" Version="4.44.0" />
</ItemGroup>
</Project>
我的理解是调用AcquireTokenInteractive()
应该自动将token存入缓存,AcquireTokenSilent()
从缓存中获取token。那为什么我会收到错误消息?我在WSL中运行这段代码,dotnet --version
returns6.0.300
.
您在 AcquireTokenInteractive
之前调用 GetAccountsAsync
,但 return 没有任何帐户。没有帐户传递给 AcquireTokenSilent
,并且此方法不知道应该为哪个帐户获取访问令牌。
调用AcquireTokenInteractive
后需要调用GetAccountsAsync
。在这种情况下,它将 return 帐户和 AcquireTokenSilent
将从指定帐户的缓存中获取令牌。
authResult = await publicClientApp
.AcquireTokenInteractive(new string[] { "user.read" })
.ExecuteAsync()
.ConfigureAwait(false);
var accounts = await publicClientApp
.GetAccountsAsync()
.ConfigureAwait(false);
IAccount? firstAccount = accounts.FirstOrDefault();
authResult = await publicClientApp
.AcquireTokenSilent(new string[] { "user.read" }, firstAccount)
.ExecuteAsync();
根据 Microsoft 在 Github 存储库中提供的示例,您只需使用 app.AddInMemoryTokenCache()
with ConfidentialClientApplicationBuilder
, and new StorageCreationPropertiesBuilder(...).WithLinuxKeyring(...)
和 PublicClientApplicationBuilder
。