C# 在ALB上使用Cognito用户池进行ASP.NET核心身份验证
我正在将一个遗留的ASP.NET MVC应用程序移植到.NET Core,我还试图替换现有的Identity框架,以使用由应用程序负载平衡器处理的AWS Cognito用户池 我有大多数的设置和工作,当请求到达ALB,未经授权的用户被重定向到Cognoto托管的登录页面,在那里他们可以登录。这一切正常,但我想将JWT(从ALB传回)中的信息连接到ASP.NET Identity framework,以便访问填充的“User”对象 包含JWT的响应头也是非标准的“X-Amzn-Oidc-Data”,而不是在标准授权中。我已经研究过使用Microsoft.AspNetCore.Authentication.JwtBearer,但我相信这需要标准授权头 我确实遇到了这个项目,它似乎正是我需要的那种东西,但它似乎已经被放弃了。有没有人有过类似的经历,可以分享同样的东西 更新:这是我们根据Mickaël的评论更新的启动代码:C# 在ALB上使用Cognito用户池进行ASP.NET核心身份验证,c#,amazon-web-services,asp.net-core,amazon-cognito,C#,Amazon Web Services,Asp.net Core,Amazon Cognito,我正在将一个遗留的ASP.NET MVC应用程序移植到.NET Core,我还试图替换现有的Identity框架,以使用由应用程序负载平衡器处理的AWS Cognito用户池 我有大多数的设置和工作,当请求到达ALB,未经授权的用户被重定向到Cognoto托管的登录页面,在那里他们可以登录。这一切正常,但我想将JWT(从ALB传回)中的信息连接到ASP.NET Identity framework,以便访问填充的“User”对象 包含JWT的响应头也是非标准的“X-Amzn-Oidc-Data”
services.AddAuthentication("Cognito")
.AddJwtBearer("Cognito", options =>
{
options.Events = options.Events ?? new JwtBearerEvents();
options.Events.OnMessageReceived = context =>
{
string amazonOidcDataHeader = context.Request.Headers["X-Amzn-Oidc-Data"];
if (!string.IsNullOrEmpty(amazonOidcDataHeader))
{
context.Token = amazonOidcDataHeader.Trim();
}
return Task.CompletedTask;
};
options.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
{
// get JsonWebKeySet from AWS
var json = new WebClient().DownloadString(parameters.ValidIssuer + "/.well-known/jwks.json");
// serialize the result
var keys = JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;
// cast the result to be the type expected by IssuerSigningKeyResolver
return (IEnumerable<SecurityKey>)keys;
},
ValidIssuer = this.Configuration["Authentication:Cognito:ValidIssuer"],
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidAudience = this.Configuration["Authentication:Cognito:ClientId"],
ValidateAudience = true
};
});
services.AddAuthentication(“Cognito”)
.AddJwtBearer(“Cognito”,选项=>
{
options.Events=options.Events??新的JWTBeareEvents();
options.Events.OnMessageReceived=上下文=>
{
字符串amazonOidcDataHeader=context.Request.Headers[“X-Amzn-Oidc-Data”];
如果(!string.IsNullOrEmpty(AmazonOIDCataHeader))
{
context.Token=amazonOidcDataHeader.Trim();
}
返回Task.CompletedTask;
};
options.TokenValidationParameters=新的TokenValidationParameters
{
IssuerSigningKeyResolver=(s、securityToken、标识符、参数)=>
{
//从AWS获取JsonWebKeySet
var json=new WebClient().DownloadString(parameters.validisuser+“/.well-known/jwks.json”);
//序列化结果
var keys=JsonConvert.DeserializeObject(json).keys;
//将结果强制转换为IssuerSigningKeyResolver期望的类型
返回(IEnumerable)键;
},
ValidIssuer=this.Configuration[“Authentication:Cognito:ValidIssuer”],
ValidateSuersigningKey=true,
validateisuer=true,
ValidateLifetime=true,
validudience=this.Configuration[“Authentication:Cognito:ClientId”],
ValidateAudience=true
};
});
现在从标头检索令牌并将其推送到上下文中。令牌属性,标识用户对象仍然不包含声明。内置JWT提供程序有一个扩展点,可以通过
JWTBeareEvents.OnMessageReceived
事件从几乎任何地方获取令牌
你可以这样做:
服务
.AddAuthentication(“Cognito”)
.AddJwtBearer(“Cognito”,选项=>
{
options.Events???=newjwtbearerevents();
options.Events.OnMessageReceived=上下文=>
{
常量字符串bearprefix=“Bearer”;
字符串amazonOidcDataHeader=context.Request.Headers[“X-Amzn-Oidc-Data”];
if(!string.IsNullOrEmpty(amazonOidcDataHeader)&&amazonOidcDataHeader.StartsWith(bearerPrefix,StringComparison.OrdinalIgnoreCase))
{
context.Token=amazonOidcDataHeader.Substring(bearerPrefix.Length).Trim();
}
返回Task.CompletedTask;
};
});
如需参考,请参阅GitHub上的此代码摘录,其中显示了处理程序的实现,以及它如何使用
MessageReceived
事件期间分配的令牌(如果有),或者尝试从标准Authorization
头中提取令牌,否则:谢谢,这非常有用。我认为这应该从JWT填充Identity User对象,对吗?没问题。是的,除了令牌的来源之外,其他所有内容都将起相同的作用,包括填充HttpContext.User
属性。我的HttpContext必须缺少一些内容。用户仍然为空,是否需要设置中间件的其他部分?增加日志记录级别以调试和分析HTTP请求的条目。如果没有完整的代码,即Startup
类,就不可能知道可能缺少什么。