Britonk
Britonk

Reputation: 181

AWS Cognito user pools on multi-tenant web app

We have a single .net Core MVC web application which will be used by multiple customers. Each customer will have a number of users.

We intend to use AWS Cognito for user authentication and reading up on this I see that a user pool per customer is one of the recommended routes. This works well for our use-case as customer A might want a user with the username "Bob" and customer B might want another user with the username "Bob".

Everything I have read suggests this should be possible but here is the issue:

In .net core I have to specify some details that are specific to a particular app pool on startup:

                .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"];

How do I go about getting the application to use multipleuser pools?

To elaborate on the above I suppose the ideal solution would be:

1) We direct the user to a specific login URL for their user pool. 2) After login user gets redirected to the central site. 3) We somehow detect which user pool they authenticated through and set ClientId and ClientSecret accordingly for the session.

Upvotes: 4

Views: 3016

Answers (2)

tgittos
tgittos

Reputation: 354

I had to solve a similar problem this week. Apparently .NET Core doesn't support this out of the box, as it can raise some tricky questions about auth challenges when dealing with a GUI based website: https://github.com/aspnet/Security/issues/1847

I was solving this problem in the context of an API server however, and it was easy to make a few underlying assumptions.

I eventually solved it by implementing my own JwtBearerHandler class that's mostly the same as the .NET Core one, but reconfigures the JwtBearerOptions on the fly based on information in the HTTP request. The most relevant changes can be found here: https://github.com/tgittos/AmazonCognitoPrototype/blob/master/AmazonCognitoSpike/Auth/CognitoUserPoolResolver.cs

Basically the gist of the solution is to pull an identifier off of the request in the JwtBearerHandler and use that to reconfigure the Audience and Authority on the JwtBearerOptions based on what's been stored in a database as the request is coming in. It doesn't add a whole lot of overhead to the request and seems to work well enough.

The whole repo I linked is a proof-of-concept I worked on to get Cognito auth working with multiple user pools, so it might be worth taking some time to read the lot. It's pretty messy and includes classes that I didn't need to replace. The core changes are in CognitoUserPoolResolver, DSJwtBearerHandler and DSJwtBearerOptions.

Upvotes: 4

Mike
Mike

Reputation: 164

If I understand correctly the key challenge is identifying the Cognito User Pool associated with the authenticated user. To solve that the ID Token issued by Cognito includes an iss claim that identifies the User Pool.

More details here,

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

Upvotes: 0

Related Questions