Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identity Server Tenant Id Mismatch on password update #868

Open
goforebroke opened this issue Aug 11, 2024 · 4 comments
Open

Identity Server Tenant Id Mismatch on password update #868

goforebroke opened this issue Aug 11, 2024 · 4 comments
Labels

Comments

@goforebroke
Copy link

goforebroke commented Aug 11, 2024

I am trying to update a users password, but keep getting a tenant id mismatch error thrown in Finbuckle

Reset password page
image

The error occurs when the user manager calls the method ResetPasswordAsync.

image

Error captured in Seq shows the user manager is failing on UpdateAsync

image

I have setup my IdentityDbContext so that it inherits from MultiTenantIdentityDbContext.

image

The data currently in the aspnet users table has two users in each tenant. The highlighted users have the same email address but are in different tenants

image

Here is my tenant table, which resides in a seperate API. All other APIs do tenant resolution to redis cache, if the tenant is not found, it goes to the http store. These are the two tenants in the table and the tenant that I am using is highlighted.

image

I ran a SQL profiler to see why there could possible be a tenant id mismatch. There are 2 statements that execute just prior to the exception and appear to be getting data belonging to the correct tenant identifier '1B8E302B-B931-4CAE-B404-A42B7D1E8895' and tenant id 'CE760000-58B6-2C33-7E0D-08DC8BE9C022'.

image

image

Do you have any idea why I am getting a tenant id mismatch? If you need more information let me know

@AndrewTriesToCode
Copy link
Sponsor Contributor

Hm, I suspect that the password reset code path somewhere calls FindAsync which bypasses the global query filter. You should be able to reimplement that method pretty easily to avoid that function.

@goforebroke
Copy link
Author

goforebroke commented Aug 12, 2024

Hi Andrew,

Thanks for getting back to me very quickly. I start the SQL trace the moment before the "PasswordReset" page is loaded.
After the reset button is pressed, the trace has only two queries in it. Both queries have the tenant id filter, with the same value, applied to them. Both queries captured in the profiler trace return the same user from the user table.

image

image

If the find method was called, I would expect to see some sort of query against the identity database without a tenant id global filter?

The error occurs when save changes in MultiTenantIdentityDbContext is called.

@AndrewTriesToCode
Copy link
Sponsor Contributor

Hi Jaime, question, is your Identity model customized at all beyond just inheriting from the multitenant identity db context? What is in the method you call inside OnModeling?

@goforebroke
Copy link
Author

goforebroke commented Aug 13, 2024

Andrew,

I have configurations for all the identity tables. The identity user has a couple of extra columns along with a non clustered index on the tenant id column that gets created automatically by Finbuckle.

public sealed class ApplicationUser : IdentityUser
{
    public DateTime? EmailConfirmationSent { get; set; }
    public string StripeCustomerId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
namespace Identity.API.Infrastructure.Persistence.Configurations
{
    public sealed class ApplicationUserConfiguration : IEntityTypeConfiguration<ApplicationUser>
    {
        public void Configure(EntityTypeBuilder<ApplicationUser> builder)
        {
            builder.Property(p => p.StripeCustomerId).HasMaxLength(64);
            builder.Property(p => p.FirstName).HasMaxLength(64).IsRequired();
            builder.Property(p => p.LastName).HasMaxLength(64).IsRequired();
            builder.HasIndex(new[] { "TenantId" }, "UX_AspNetUsers_TenantId");
        }
    }
}

The remaining tables just create a non clustered index on the tenant id column in their respective configurations

    public class ApplicationRole : IdentityRole
    {
    }
namespace Identity.API.Infrastructure.Persistence.Configurations
{
    public sealed class ApplicationRoleConfiguration : IEntityTypeConfiguration<ApplicationRole>
    {
        public void Configure(EntityTypeBuilder<ApplicationRole> builder)
        {
            builder.HasIndex(new[] { "TenantId" }, "IX_AspNetRoles_TenantId");
        }
    }
}

Other areas work fine without any issues such as registration, login and logout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 participants