Asp.net web api 如何在.NETCore3.1WebAPI的Cognito标识池中用JWT令牌交换凭据
概述:我正在尝试创建一个.Net Core 3.1 WebApi后端,该后端通过Amazon Cognito的身份验证。我想使用Cognito提供的亚马逊托管登录页面。我想利用Cognito标识池在用户登录后为他们提供临时范围的凭证。我不知道如何交换Cognoto令牌来创建调用AWS服务的凭据 技术概述Asp.net web api 如何在.NETCore3.1WebAPI的Cognito标识池中用JWT令牌交换凭据,asp.net-web-api,jwt,amazon-cognito,openid-connect,asp.net-core-3.1,Asp.net Web Api,Jwt,Amazon Cognito,Openid Connect,Asp.net Core 3.1,概述:我正在尝试创建一个.Net Core 3.1 WebApi后端,该后端通过Amazon Cognito的身份验证。我想使用Cognito提供的亚马逊托管登录页面。我想利用Cognito标识池在用户登录后为他们提供临时范围的凭证。我不知道如何交换Cognoto令牌来创建调用AWS服务的凭据 技术概述 .NET核心3.1 WebApi 用于初始身份验证的Amazon Cognito用户池 用于为登录用户定义权限(角色)的Amazon标识池 使用AWS无服务器框架(基本上是CloudForma
- .NET核心3.1 WebApi
- 用于初始身份验证的Amazon Cognito用户池
- 用于为登录用户定义权限(角色)的Amazon标识池
- 使用AWS无服务器框架(基本上是CloudFormation)通过API网关+Lambda在AWS上部署
- 将[Authorize]属性添加到控制器端点,并在浏览器中访问URL。这会将我重新引导到Cognito托管的登录页面,并在成功登录后将我返回到控制器/端点,我获得授权
- 创建一个单独的客户端应用程序并登录到AWS Cognito。当从客户端调用API时,在授权HTTP头中传递JWT令牌,授权成功并授予API访问权
RegionEndpoint region = Configuration.GetAWSOptions().Region;
services.AddScoped(_ => new CognitoAWSCredentials(Settings.CognitoIdentityPoolId, region));
我已经创建了一个事件处理程序,它在触发OpenIdConnect事件“OnTokenValidated”时被触发。这发生在我登录到Cognito托管的web UI并被重定向回API之后
在此处理程序中,我可以调用:
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
creds.AddLogin( ... ??? ...);
相关数据结构
在可以调用AddLogin的事件处理程序中,我可以访问:Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenValidatedContext
,其中特别包含:
with:Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage
- 访问令牌
- 身份证
- 刷新令牌
带有:System.IdentityModel.Tokens.Jwt.JwtSecurityToken
iss
值作为AddLogin中的providerName,以及access\u令牌
或id\u令牌
,但都不起作用
有人知道我需要使用什么来添加登录,以便Cognito基于Cognito用户池登录的JWT令牌为我创建身份池凭据吗?除非我错过了,否则我没有看到说明这一点的文档,但是,即使各种数据结构上的所有Issuer字段都包含“https://”,在使用Issuer作为
AddLogin
调用上的providerName
之前,您仍需要将其删除。啊
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
string shortIssuer = tokenValidatedContext.SecurityToken.Issuer;
if (shortIssuer.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("https://".Length);
if (shortIssuer.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("http://".Length);
creds.AddLogin(shortIssuer, tokenValidatedContext.TokenEndpointResponse.IdToken);
(一些代码被删除,专门关注OpenId Connect事件和CognitoAWSCredentials init)除非我错过了它,否则我还没有看到说明这一点的文档,但即使各种数据结构上的所有Issuer字段都包括“https://”,在使用发卡机构作为
AddLogin
调用上的providerName
之前,需要将其剥离。啊
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
string shortIssuer = tokenValidatedContext.SecurityToken.Issuer;
if (shortIssuer.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("https://".Length);
if (shortIssuer.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("http://".Length);
creds.AddLogin(shortIssuer, tokenValidatedContext.TokenEndpointResponse.IdToken);
(删除了一些代码,专门关注OpenId Connect事件和CognitoAWSCredentials init)
{
{
"alg": "RS256",
"kid": "**************************"
}. {
"at_hash": "**************************",
"sub": "**************************",
"email_verified": true,
"iss": "https://cognito-idp.ca-central-1.amazonaws.com/**************************",
"cognito:username": "**************************",
"nonce": "**************************",
"aud": "**************************",
"event_id": "**************************",
"token_use": "id",
"auth_time": 1595260191,
"exp": 1595263791,
"iat": 1595260191,
"email": "**************************"
}
}
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
string shortIssuer = tokenValidatedContext.SecurityToken.Issuer;
if (shortIssuer.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("https://".Length);
if (shortIssuer.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("http://".Length);
creds.AddLogin(shortIssuer, tokenValidatedContext.TokenEndpointResponse.IdToken);
services...<other authentication setup>...
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.ClientId = Settings.CognitoClientId;
options.MetadataAddress = CognitoMetadataAddress;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.UsePkce = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidIssuers = new string[] { Settings.CognitoAuthority },
ValidateAudience = true,
ValidAudiences = new string[] { Settings.CognitoClientId }
};
options.Events = new OpenIdConnectEvents() {
OnTokenValidated = tokenValidatedContext => {
CognitoAWSCredentials creds = services.BuildServiceProvider().GetRequiredService<CognitoAWSCredentials>();
string shortIssuer = tokenValidatedContext.SecurityToken.Issuer;
if (shortIssuer.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("https://".Length);
if (shortIssuer.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) shortIssuer = shortIssuer.Substring("http://".Length);
creds.AddLogin(shortIssuer, tokenValidatedContext.TokenEndpointResponse.IdToken);
return Task.CompletedTask;
}
};
})