折腾了2天,投入了6个小时左右,我终于决定寻求帮助。
我有一个带有 MSAL 身份验证的独立 Blazor WASM 应用程序,在登录成功并尝试获取访问 token 后,我收到错误消息:
blazor.webassembly.js:1 info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
Authorization was successful.
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: An exception occurred executing JS interop: The JSON value could not be converted to System.DateTimeOffset. Path: $.token.expires | LineNumber: 0 | BytePositionInLine: 73.. See InnerException for more details.
Microsoft.JSInterop.JSException: An exception occurred executing JS interop: The JSON value could not be converted to System.DateTimeOffset. Path: $.token.expires | LineNumber: 0 | BytePositionInLine: 73.. See InnerException for more details.
---> System.Text.Json.JsonException: The JSON value could not be converted to System.DateTimeOffset. Path: $.token.expires | LineNumber: 0 | BytePositionInLine: 73.
---> System.InvalidOperationException: Cannot get the value of a token type 'Null' as a string.
at System.Text.Json.Utf8JsonReader.TryGetDateTimeOffset(DateTimeOffset& value)
at System.Text.Json.Utf8JsonReader.GetDateTimeOffset()
此错误仅在我登录后显示。我的设置在 .NET 5.0 上运行,身份验证提供程序是 Azure B2C 租户,我将重定向 URI 正确配置为“单页应用程序”,并将权限授予“offline_access”和“openid”。
这是我的 Program.cs
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// Authenticate requests to Function API
builder.Services.AddScoped<APIFunctionAuthorizationMessageHandler>();
//builder.Services.AddHttpClient("MyAPI",
// client => client.BaseAddress = new Uri("<https://my_api_uri>"))
// .AddHttpMessageHandler<APIFunctionAuthorizationMessageHandler>();
builder.Services.AddMudServices();
builder.Services.AddMsalAuthentication(options =>
{
// Configure your authentication provider options here.
// For more information, see https://aka.ms/blazor-standalone-auth
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.LoginMode = "redirect";
options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
});
await builder.Build().RunAsync();
}
}
我特意注释掉了 AuthorizationMessageHandler 的 HTTPClient 链接。“AzureAD”配置具有设置为 true 的 Authority、ClientId 和 ValidateAuthority。
public class APIFunctionAuthorizationMessageHandler : AuthorizationMessageHandler
{
public APIFunctionAuthorizationMessageHandler(IAccessTokenProvider provider,
NavigationManager navigationManager)
: base(provider, navigationManager)
{
ConfigureHandler(
authorizedUrls: new[] { "<https://my_api_uri>" });
//scopes: new[] { "FunctionAPI.Read" });
}
}
我已经尝试定义诸如 openid 或自定义 API 范围之类的范围,但现在没有。没有不同。然后导致异常,我正在做的事情很简单:
@code {
private string AccessTokenValue;
protected override async Task OnInitializedAsync()
{
var accessTokenResult = await TokenProvider.RequestAccessToken();
AccessTokenValue = string.Empty;
if (accessTokenResult.TryGetToken(out var token))
{
AccessTokenValue = token.Value;
}
}
}
最终目标是使用这样的东西: try {
var httpClient = ClientFactory.CreateClient("MyAPI");
var resp = await httpClient.GetFromJsonAsync<APIResponse>("api/Function1");
FunctionResponse = resp.Value;
Console.WriteLine("Fetched " + FunctionResponse);
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
但是返回了相同的错误,甚至在运行之前看起来如此。此代码也是 Blazor 组件的 OnInitializedAsync()。
欢迎任何想法或建议。
我被困住了,有点绝望。
我怀疑没有从 Azure AD B2C 请求或返回访问 token ,但假设这是 AuthorizationMessageHandler 作业。
非常感谢任何欢迎。
谢谢。
最佳答案
发现问题。
在 JavaScript 端做了一些调试后,文件 AuthenticationService.js,美化后第 171 行的方法“async getTokenCore(e)”,我已经确认实际上没有返回访问 token ,只有 IdToken。
通过阅读有关向 Azure AD B2C 请求访问 token 的文档,它提到根据您定义的范围,它将更改返回给您的内容。
范围“openid”告诉它您需要一个 IdToken,然后“offline_access”告诉它您需要一个刷新 token ,最后有一个绝妙的技巧,您可以在其中定义 App Id 的范围,它会返回一个访问 token 。
更多详情:https://docs.microsoft.com/en-us/azure/active-directory-b2c/access-tokens#openid-connect-scopes
所以我在 Program.cs、builder.Services.AddMsalAuthentication 步骤中更改了我的代码。
现在它看起来像这样:
builder.Services.AddMsalAuthentication(options =>
{
// Configure your authentication provider options here.
// For more information, see https://aka.ms/blazor-standalone-auth
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.LoginMode = "redirect";
options.ProviderOptions.DefaultAccessTokenScopes.Add("00000000-0000-0000-0000-000000000000");
//options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
//options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
});
我设置了我在这个 Blazor 应用程序上使用的实际应用程序 ID,而不是“00000000-0000-0000-0000-000000000000”。现在错误没有发生并且返回了访问 token 。
谢谢。
关于c# - Blazor 独立 WASM 无法使用 MSAL 获取访问 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68553637/