Reputation: 181
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
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
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,
Upvotes: 0