多租户 Web 应用程序上的 AWS Cognito 用户池

AWS Cognito user pools on multi-tenant web app

我们有一个 .net Core MVC Web 应用程序,将由多个客户使用。每个客户都会有一些用户。

我们打算使用 AWS Cognito 进行用户身份验证,仔细阅读后我发现每个客户一个用户池是推荐的路线之一。这对我们的用例很有效,因为客户 A 可能想要一个用户名为 "Bob" 的用户,而客户 B 可能想要另一个用户名为 "Bob".

的用户

我读过的所有内容都表明这应该是可能的,但问题是:

在 .net 核心中,我必须在启动时指定特定于特定应用程序池的一些细节:

                .AddOpenIdConnect(async options =>
            {
                options.ResponseType = OpenIdConnectResponseType.Code;

                options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
                                                services.BuildServiceProvider().GetService<IOpenIdDiscovery>().OpenIdConfigurationUrl(),
                                                new OpenIdConnectConfigurationRetriever(),
                                                services.BuildServiceProvider().GetService<System.Net.Http.HttpClient>());

                options.Authority = Configuration["OpenIdAuthority"];
                options.ClientId = Configuration["AuthCodeClientId"];
                options.ClientSecret = Configuration["AuthCodeClientSecret"];

如何让应用程序使用多用户池?

为了详细说明以上内容,我认为理想的解决方案是:

1) 我们将用户引导至其用户池的特定登录 URL。 2)登录用户被重定向到中央站点后。 3) 我们以某种方式检测他们通过哪个用户池进行身份验证,并相应地为会话设置 ClientId 和 ClientSecret。

如果我理解正确的话,关键挑战是识别与经过身份验证的用户关联的 Cognito 用户池。解决 Cognito 发布的 ID 令牌包含标识用户池的 iss 声明。

更多详情,

https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html

这周我不得不解决类似的问题。显然.NET Core 不支持开箱即用,因为在处理基于 GUI 的网站时,它可能会引发一些关于身份验证挑战的棘手问题:https://github.com/aspnet/Security/issues/1847

不过,我是在 API 服务器的上下文中解决这个问题的,因此很容易做出一些基本假设。

我最终通过实现我自己的 JwtBearerHandler class 解决了这个问题,它与 .NET Core 大部分相同,但是根据HTTP 请求。可以在此处找到最相关的更改:https://github.com/tgittos/AmazonCognitoPrototype/blob/master/AmazonCognitoSpike/Auth/CognitoUserPoolResolver.cs

基本上,解决方案的要点是从 JwtBearerHandler 中的请求中提取一个标识符,并使用它来重新配置 [=11= 中的 AudienceAuthority ] 基于请求传入时存储在数据库中的内容。它不会给请求增加很多开销,而且似乎工作得很好。

我链接的整个存储库是我致力于让 Cognito 身份验证与多个用户池一起工作的概念验证,因此可能值得花一些时间阅读很多内容。它非常混乱,包括 class 我不需要更换的东西。核心变化在 CognitoUserPoolResolverDSJwtBearerHandlerDSJwtBearerOptions.