技术目标:
- 客户端:Blazor WebAssembly
- 后端: .NET Core 3.1 WebApi on Lambda (AWS) via ApiGateway (/{proxy+})
- 身份验证:AWS Cognito
后端:
- 我有一个 .NET Core Lambda 函数,可以通过 ApiGateway /{proxy+} => Lambda 通过 AWS ApiGateway (RestApi) 访问。这部署和工作正常。我已将 WebApi 配置为使用 AWS Cognito 作为其身份验证方法(下面的 Startup..cs:ConfigureServices 代码)。
- 我可以在我的路由上成功使用 [Authorize] 属性,当我直接在浏览器中使用 [Authorize] 访问路由时,我会被发送到 Cognito 签名页面,我可以登录并被发送回我的 Api 和调用执行。效果很好。
Startup.cs:配置服务
RegionEndpoint region = Configuration.GetAWSOptions().Region;
string CognitoMetadataAddress = $"https://cognito-idp.{region.SystemName}.amazonaws.com/{AppConfig.CognitoPoolId}/.well-known/openid-configuration";
//
// Ref: https://criticalhittech.com/2019/02/19/asp-net-core-with-aws-lambda-and-cognito/
//
services.Configure<OpenIdConnectOptions>(options =>
{
options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;
options.ClientId = AppConfig.CognitoClientId;
options.MetadataAddress = CognitoMetadataAddress;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true
};
});
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.ClientId = AppConfig.CognitoClientId;
options.MetadataAddress = CognitoMetadataAddress;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true
};
options.Events = new OpenIdConnectEvents()
{
OnRedirectToIdentityProvider = OnRedirectToIdentityProvider,
OnRedirectToIdentityProviderForSignOut = OnRedirectToIdentityProviderForSignOut,
OnAuthenticationFailed = OnAuthenticationFailed,
OnUserInformationReceived = OnUserInformationReceived
};
});
客户端:
- 我有一个使用 WebAssembly 的基本 Blazor 项目(因此我最终可以将编译后的静态输出放到 AWS S3 上并将其托管在那里)。
- 我已将项目配置为使用 Cognito 作为其身份验证源(请参阅下面的 Program.cs:Main 代码)并且它工作“正常”(它当然有愚蠢的 Cognito X-Frame-Options 问题,但它可以工作)。
程序.cs:主要
string CognitoPoolId = "ca-central-1_<REMOVED>";
string region = CognitoPoolId.Substring(0, CognitoPoolId.IndexOf('_', StringComparison.InvariantCultureIgnoreCase));
string CognitoAuthority = $"https://cognito-idp.{region}.amazonaws.com/{CognitoPoolId}";
string CognitoMetadataAddress = $"https://cognito-idp.{region}.amazonaws.com/{CognitoPoolId}/.well-known/openid-configuration";
builder.Services.AddOidcAuthentication(options =>
{
options.ProviderOptions.Authority = CognitoAuthority;
options.ProviderOptions.MetadataUrl = CognitoMetadataAddress;
options.ProviderOptions.ClientId = "<REMOVED>";
options.ProviderOptions.RedirectUri = $"{builder.HostEnvironment.BaseAddress.TrimEnd('/')}/authentication/login-callback";
options.ProviderOptions.ResponseType = "code";
});
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
问题 在我的 Blazor 应用程序中,我想调用我的后端 API(需要身份验证)并使用 Blazor 应用程序已经拥有的授权,因为客户端和后端都使用相同的 Cognito 用户池。IE
- 加载 Blazor 应用
- 完成登录
- 对我的后端进行 Http 调用 <--使用 #2 中的登录会话
HttpResponseMessage response = await Http.SendAsync(requestMessage);
如何配置 HttpClient 实例以通过使用 Cognito 进行身份验证来发送 Blazor 应用程序具有的授权,以便它可以调用受保护的 API?