Blazor WASM - 我的客户端应用程序使用 Google 身份验证。如何验证对 Web API 的请求?

问题描述 投票:0回答:1

我将 Google OIDC 身份验证添加到我的 Blazor WASM 应用程序中:

builder.Services.AddOidcAuthentication(options =>
{
    // Configure your authentication provider options here.
    // For more information, see https://aka.ms/blazor-standalone-auth
    builder.Configuration.Bind("Local", options.ProviderOptions);

    options.ProviderOptions.Authority = "https://accounts.google.com";
    options.ProviderOptions.ClientId = "big-number.apps.googleusercontent.com";
    options.ProviderOptions.RedirectUri = builder.HostEnvironment.BaseAddress + "authentication/login-callback";
    options.ProviderOptions.PostLogoutRedirectUri = builder.HostEnvironment.BaseAddress + "authentication/logout-callback";
    
    options.ProviderOptions.DefaultScopes.Add("openid");
    options.ProviderOptions.DefaultScopes.Add("profile");
    options.ProviderOptions.ResponseType = "id_token token";
});

我能够通过谷歌进行身份验证,检索自动存储在会话和/或本地存储中的信息,并且

AuthenticationStateProvider
现在显示我已通过身份验证。因此客户端身份验证正在按需要运行。

我的问题是,对浏览器客户端进行身份验证后,在对 ASP.NET Core Web API 进行 CORS 调用时如何利用此已确认的身份?

另外:

  1. 我可以(并且应该)将 JWT 传递给 Web API 吗?
  2. 我应该发送哪个令牌?会话存储中的数据包括
    id_token
    access_token
    (我上面提到了“JWT”,但由于我收到了多条信息,所以我不知道“JWT”指的是哪一个) )
  3. 我应该如何获取 JWT 才能将其发送到 Web API?我目前知道的唯一方法是从会话存储中检索它(例如,使用
    Blazored.SessionStorage
    ),但这似乎是一种笨拙且可能容易出错的方法(我需要找出计时问题等)
  4. 如何将相关信息附加到
    HttpClient
    ?我可以做类似
    client.DefaultRequestHeaders.Add("GOOGLE-JWT", jwt)
    的事情,但是有没有一种规范的更好的方法来建立这种联系?
  5. 在 Web API 中,是否可以使用
    builder.Services.AddAuthentication()
    app.UseAuthentication()
    将令牌转换为“标准”ASP.NET Core 用户信息?如果是这样,我该怎么做?

我可以通过执行上述步骤来传递信息(从会话存储中检索令牌数据,将其作为标头,并在自定义中间件中处理 Web API 中的标头信息)。但感觉应该有“更平滑”的方式来完成其中部分或全部这些事情,而且我不知道我正在做的事情是否足够“安全”。

或者,如果这对于与 Web API 通信的静态 WASM 应用程序来说不是合适的身份验证流程,我应该采取哪些不同的做法?

blazor google-oauth asp.net-core-webapi blazor-webassembly
1个回答
0
投票

“idtoken”不是用于身份验证目的的真正令牌,而是用于加密用户附加信息。您只需在 httpclient 中添加

AccessToken
即可调用受“jwt 承载身份验证”保护的后端。

无需使用“OpenIddcit”。一般来说,在 WASM 中配置了

AddOidcAuthentication
,您可以使用
IAccessTokenProvider
获取 AccessToken 并将其添加到 httpclient,如下所示:

@inject IAccessTokenProvider TokenProvider
@inject HttpClient Http
protected override async Task OnInitializedAsync()
{
    // Request access token
    var tokenResult = await TokenProvider.RequestAccessToken();

    if (tokenResult.TryGetToken(out var token))
    {
        // Attach the access token to HttpClient
        Http.DefaultRequestHeaders.Authorization =
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token.Value);

        // Make a call to the secure Web API
        var response = await Http.GetAsync("https://localhost:5003/api/values");

        if (response.IsSuccessStatusCode)
        {
            var data = await response.Content.ReadAsStringAsync();
            Console.WriteLine(data);
        }
        else
        {
            Console.WriteLine($"API call failed: {response.StatusCode}");
        }
    }
    else
    {
        Console.WriteLine("Failed to obtain access token.");
    }
}

此httpclient能够调用配置了jwt承载身份验证的webapi后端

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.Authority = "https://accounts.google.com"; // Google's authority
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateAudience = true,
        ValidAudience = "YOUR_GOOGLE_CLIENT_ID", // Your Google Client ID
        ValidateLifetime = true
    };
});

builder.Services.AddAuthorization();

当然,您可以通过

HttpContext.User

在承载保护控制器中获取用户身份
© www.soinside.com 2019 - 2024. All rights reserved.