Blazor WASM集成Google OIDC后,如何向Web API认证请求?
我已经为Blazor WASM应用配置了Google OIDC认证,代码如下:
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"; });
目前客户端已完成Google认证,会话/本地存储存储了认证信息,AuthenticationStateProvider显示已认证,客户端认证功能正常。
核心问题
已完成浏览器客户端认证后,如何在向ASP.NET Core Web API发起CORS请求时复用该已确认身份?
疑问解答
1. 是否可以(且应该)将JWT传递给Web API?
可以且应该。JWT是标准化的身份凭证,Web API可通过验证JWT的签名和有效性确认用户身份,这是前后端分离场景下的主流身份传递方式,只要使用HTTPS传输,安全性有保障。
2. 应发送哪个令牌?会话存储中包含id_token和access_token,不清楚应选用哪个?
- id_token:仅用于客户端确认用户身份,包含姓名、邮箱等基本信息,不适合传给Web API做授权。
- access_token:是Google颁发的资源访问授权凭证,专门用于访问受保护资源(如你的Web API)。需确保认证时请求了对应Web API的权限范围,否则要调整
DefaultScopes添加对应API scope。
总结:优先使用access_token传递给Web API。
3. 如何获取要发送给Web API的JWT?目前仅知道通过Blazored.SessionStorage从会话存储中获取,但该方式繁琐且易出错(需处理时序问题等)
不需要手动操作会话存储,Blazor的AuthenticationStateProvider已封装令牌获取逻辑,通过以下方式安全获取:
@inject AuthenticationStateProvider AuthStateProvider // 在组件或服务中 var authState = await AuthStateProvider.GetAuthenticationStateAsync(); var accessToken = await authState.User.GetTokenAsync("access_token");
GetTokenAsync会自动从认证存储中获取指定类型的令牌,无需手动处理会话存储的时序问题。
4. 如何将相关信息附加到HttpClient?目前可通过client.DefaultRequestHeaders.Add("GOOGLE-JWT", jwt)实现,但是否有更规范的方式?
更规范的是使用Bearer令牌认证头,这是OAuth2/OIDC的标准做法:
// 在HttpClient中添加Authorization头 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
如果要全局为所有API请求自动附加令牌,可配置命名HttpClient并添加AddHttpMessageHandler:
// Program.cs中注册HttpClient builder.Services.AddHttpClient("ApiClient", client => { client.BaseAddress = new Uri("https://your-api-url.com/"); }) .AddHttpMessageHandler<AuthorizationMessageHandler>(); // 注册AuthorizationMessageHandler builder.Services.AddScoped<AuthorizationMessageHandler>(sp => { var handler = new AuthorizationMessageHandler(sp.GetRequiredService<IAccessTokenProvider>()); handler.ConfigureHandler( authorizedUrls: new[] { "https://your-api-url.com/" }, scopes: new[] { "your-api-scope" }); // 若API需要特定scope需填写 return handler; });
注入命名为"ApiClient"的HttpClient后,所有请求会自动携带有效access_token。
5. 在Web API中,能否通过builder.Services.AddAuthentication()和app.UseAuthentication()将令牌转换为标准ASP.NET Core用户信息?若可以,具体如何实现?
可以,Web API可通过配置Google JWT认证自动验证令牌并转换为ClaimsPrincipal:
步骤1:安装NuGet包
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
步骤2:配置认证服务(Program.cs)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = "https://accounts.google.com"; options.Audience = "your-web-api-client-id"; // 若API是Google Cloud服务,填API客户端ID;自建API需验证issuer和audience options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = "https://accounts.google.com", ValidateAudience = true, ValidAudience = "your-web-api-client-id", // 不验证audience可设为false,但不推荐 ValidateLifetime = true }; }); // 启用认证和授权中间件 app.UseAuthentication(); app.UseAuthorization();
步骤3:在API控制器或方法上添加授权特性
[Authorize] [ApiController] [Route("api/[controller]")] public class ValuesController : ControllerBase { [HttpGet] public IActionResult Get() { // 访问用户信息 var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var email = User.FindFirstValue(ClaimTypes.Email); return Ok(new { UserId = userId, Email = email }); } }
当前自定义中间件方式的安全性说明
如果使用HTTPS传输,将令牌放在请求头中是安全的,但手动处理令牌容易出现令牌过期、存储不当等问题,建议改用上述标准化方案,减少手动操作的风险。
替代方案(若当前流程不适用于静态WASM+Web API)
如果当前OIDC复用流程不符合需求,可考虑以下方案:
- API网关代理认证:在WASM和Web API之间加API网关,由网关处理Google OIDC认证,WASM只需向网关发送请求,网关验证令牌后转发给Web API。
- 后端认证代理:Web API添加端点,让WASM将Google授权码传给Web API,由Web API向Google交换令牌并管理会话,WASM后续使用Web API颁发的会话令牌访问资源。
- 使用Azure AD B2C或Auth0等身份提供商:这类服务提供更简化的前后端身份集成方案,支持WASM和Web API无缝认证。
内容的提问来源于stack exchange,提问作者Overlord Zurg

