Closed mcinnes01 closed 4 years ago
@mcinnes01 Hm, your code here looks ok. Do you have a project I can look at to see the problem when the app is running?
As a test, I would set up a simple controller and in its dependency injection get IOptions<IdentityServerAuthenticationOptions>
and check the values within the controller to see if they were set for the tenant.
It's possible that IdentityServer is using these options during setup when there is no tenant and caching them--thus no tenant specific options are ever created/used. In that case things will be a bit more complicated. I will have some time to look into this over the next few weeks.
Hi, I was able to get this to work today using the IdentityServer4 Quick Start Sample 1 for the client credential flow. I will clean up my sample and post it on GitHub later. Here are some thoughts:
app.UseMultiTenant()
before app.UseAuthentication()
in Startup.Configure
so that the tenant will be set and the correct options will be created.IdentityServerAuthenticationOptions
should work just fine per-tenant.Finally, you will need another per-tenant option call like this:
WithPerTenantOptions<JwtBearerOptions>((options, tenantInfo) =>
{
options.TokenValidationParameters.ValidAudience = (string)tenantInfo.Items["ApiName"];
}
This is because IdentityServer is using this setting internally and it will "stick" to the first tenant that uses it unless you add the code above so that it is also per-tenant.
Good luck!
Hi
Great stuff, I'll try out your ideas above shortly and let you know how I get on. Does this deal with dynamically resolving the clients per tenant? I'd made an implementation of IClientStore whilst playing with it, and I resolved the tenant from the context to build tenant specific clients. I guess what would be cool is if I cached them and then resolved them by tenant id.
Good work and I look forward to seeing your example :)
Out of interest, in SaasKit there is a per tenant container implementation, is there something similar in Finbuckle or do you suggest a different approach, I know you mentioned IOptions, but I guess there are scenarios that won't lend well to that? Is a tenant scoped container something you've thought about incorporating?
Many thanks
Andy
@mcinnes01, I haven't played with IClientStore
yet--but I think MultiTenantDbContext
(similar to MultiTenantIdentityDbCotext
but without Identity stuff) could be used to good effect.
With respect a per-tenant container, do you mean a per-tenant dependency injection container? I haven't put too much thought into it. I thought maybe a "Tenant" lifetime option next to Singleton, Scoped, and Transient might be good, but using WithPerTenantOptions
Scoped and Transient are already per-tenant. The only thing that a "Tenant" lifetime would potentially handle are Singleton items. I didn't have a need so I didn't pursue it.
I think SaasKit also does per tenant pipelines. Is that what you were referring to? I know that's how they did per tenant authentication in ASP.NET Core 1, but with ASP.NET Core 2 that method doesn't work well. I haven't looked into having a custom pipeline since I haven't needed it for anything.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Hi,
I know there was a bug you fixed where Items weren't being set, so I've pulled master down so it is correctly setting the items on TenantInfo. However in WithPerTenantOptions, when I try to access items, there are no items available.
This is where I set them called from the Configure method: