Finbuckle / Finbuckle.MultiTenant

Finbuckle.MultiTenant is an open-source multitenancy middleware library for .NET. It enables tenant resolution, per-tenant app behavior, and per-tenant data isolation.
https://www.finbuckle.com/multitenant
Apache License 2.0
1.33k stars 265 forks source link

[BUG] NullReferenceException when multiple authentication schemes are configured #765

Closed JonasDev17 closed 9 months ago

JonasDev17 commented 1 year ago

Seems like when you configure multiple authentication schemes, it fails to get the TenantInfo.

I have asked about it here:

https://stackoverflow.com/questions/77372700/c-sharp-asp-net-core-nullreferenceexception-when-using-multiple-authentication?noredirect=1#comment136403049_77372700

JonasDev17 commented 1 year ago

I removed Finbuckle.Multitenant and Authentication worked perfectly fine

JonasDev17 commented 1 year ago

My project is: https://github.com/fullstackhero/dotnet-webapi-boilerplate but I made some changes to Infrastructure/Auth/AzureAd/Startup.cs and copied Jwt bearer from /Infrastructure/Auth/Jwt/Startup.cs over and configured my AzureAd in Host/Configurations/security.json

JonasDev17 commented 1 year ago

So I have been digging around in the code of Finbuckl.Multitenant and it seems to be in EntityTypeBuilderExtensions.cs where the expression is built, TenantInfo.Id seems to be null so the expression fails. But no idea why IMultiTenantDbContext.TenantInfo is null...

@AndrewTriesToCode your help would be highly appreciated as I have been trying to fix this bug for days now...

AndrewTriesToCode commented 1 year ago

Hi, sure I will take a look this weekend. Quick question, at what point in the application is the db context being created? App startup? During a request?

JonasDev17 commented 1 year ago

Hi, sure I will take a look this weekend. Quick question, at what point in the application is the db context being created? App startup? During a request?

Appreciate it very much! The dbcontext is created during a request (scoped).

.AddScoped<IApplicationDbContext>(provider => provider.GetService<ApplicationDbContext>())

AndrewTriesToCode commented 1 year ago

@JonasDev17 it took me a while to get to the root of it. Long story short the tenant isn't set because the the ClaimsStrategy is called with no auth scheme designated so it will use the default authentication scheme -- which in your app is the Identity.Application scheme which obviously isn't applicable for this api call.

In your Finbuckle config I added the desired scheme and I got the person profile back as expected:

.AddMultiTenant<FSHTenantInfo>()
                .WithClaimStrategy(FSHClaims.Tenant, "JWT_SCHEME") // note the scheme.

Alternatively you could make the jwt scheme the default authenticate scheme in your authentication setup.

Let me know if this resolves the issue for you and if so please update the item on Stack Overflow. I need to check the docs and if this behavior isn't there then add a description.

Now, it occurs to me that you might want to try claims on a few different schemes. The WithClaimStrategy helper method registers the strategy as a singleton so only the last one registered now would actually get checked -- I will probably need to make it be scoped or transient in a future update. It can be worked around if needed.

JonasDev17 commented 1 year ago

@AndrewTriesToCode thank you so much, that worked! However as you already mentioned, I need to try claims on multiple schemes, as I want to be able to use tokens from two different auth providers. What workaround would you suggest? I provided my own workaround in the PR #766.

aiovn commented 1 year ago

I have same issue.

AndrewTriesToCode commented 1 year ago

Min, did the solution for @JonasDev17 above also work for you?

aiovn commented 12 months ago

I saw that FSH didn't implement Finbuckle as sample: https://github.com/Finbuckle/Finbuckle.MultiTenant/tree/main/samples/net6.0 Let's me tried.

JonasDev17 commented 12 months ago

@min-hung If you are indeed having the same issue as me, I provided the solution here. You need to implement a custom strategy.

aiovn commented 12 months ago

@AndrewTriesToCode please add new api project sample which use Asp.Net Core Identity + Finbuckle.MultiTenant + Jwt authentication. For newbie, I tried build but I can't

aiovn commented 12 months ago

@min-hung If you are indeed having the same issue as me, I provided the solution here. You need to implement a custom strategy.

Actually, I just implement Asp.Net Core Identity + Finbuckle.MultiTenant. When I get users then system throw Object reference not set to an instance of an object.

aiovn commented 12 months ago

This is exactly what I'm experiencing #642

AndrewTriesToCode commented 12 months ago

@min-hung do you mind opening a separate issue for your situation and provide some of your setup code?

doanhuybinh90 commented 5 months ago

My project is: https://github.com/fullstackhero/dotnet-webapi-boilerplate but I made some changes to Infrastructure/Auth/AzureAd/Startup.cs and copied Jwt bearer from /Infrastructure/Auth/Jwt/Startup.cs over and configured my AzureAd in Host/Configurations/security.json

Hi @JonasDev17

Can you share me the way to do that ?