Authentication 带JWTs的多租户身份验证策略

Authentication 带JWTs的多租户身份验证策略,authentication,asp.net-core,jwt,Authentication,Asp.net Core,Jwt,我正在创建一个多租户的ASP.NET核心应用程序,其中用户可以属于一个或多个租户。当用户尝试进行身份验证时,我希望生成一个声明为userId和tenantId的JWT,这样api就可以使用这些值,而不是每次都必须通过route或body对象传递它们。目前,如果一个用户只与一个租户关联,那么很容易,我只需使用与他们关联的唯一租户生成JWT tenantId声明。但是如果用户与多个用户关联,那么我的策略是什么 为了从用户界面的角度清晰起见,请想象一个标准的电子邮件/密码登录表单。如果关联到一个租户,

我正在创建一个多租户的ASP.NET核心应用程序,其中用户可以属于一个或多个租户。当用户尝试进行身份验证时,我希望生成一个声明为userId和tenantId的JWT,这样api就可以使用这些值,而不是每次都必须通过route或body对象传递它们。目前,如果一个用户只与一个租户关联,那么很容易,我只需使用与他们关联的唯一租户生成JWT tenantId声明。但是如果用户与多个用户关联,那么我的策略是什么

为了从用户界面的角度清晰起见,请想象一个标准的电子邮件/密码登录表单。如果关联到一个租户,请转到该租户登录页。如果关联到多个租户,则转到租户选择屏幕

目前我认为我将有两种“类型”的JWT令牌,一种是UserToken,另一种是TenantUserToken。UserToken本质上只是一封成功通过身份验证的电子邮件/密码的用户ID,然后可以用来访问几个端点,例如查看UserToken的用户ID与哪个联盟相关,或者执行与任何特定租户无关的一般用户管理工作。TenantUserToken将是使用tenantId完全填写的令牌,并且将是大多数租户操作端点的主身份验证程序。以下是我的想法的概括:

AppToken AuthenticateUser(string email, string password, int? tenantId)
{
    var user = ValidateUser(email, password);

    if(user == null){
        //return error "email and/or password incorrect"
    }

    if(tenantId != null){
        bool valid = ValidateTenantUser(user, tenantId);

        if(valid){
            //return error "user does not have access to tenant"
        }else{
            //return TenantUserToken
        }
     }

     if(user.associatedTenants.count != 1){
         //return UserToken
     }else{
         //return TenantUserToken
     }
}

public class AppToken{
    public string Token;
    public TokenType TokenType; //enum of TenantUserToken or UserToken
}

我很可能想得太多了,但我已经花了足够长的时间在这上面了,我想我会伸出手来看看是否有其他人有想法?

您可以将所有租户id存储在令牌中(如果合适),并存储一个额外的声明,即活动租户id。然后切换租户当然需要生成一个新令牌。只是一个想法:)@juunas我也考虑过这样的事情。通过将可用租户存储在令牌上,我也可以省去前往DB获取租户列表的时间,但正如您提到的,任何时候我都想分配一个活动租户,我将生成一个新令牌。为当前租户使用cookie。嗨,Ben,你最终得到了什么解决方案?我们也面临同样的问题,并且考虑在用户更改为另一个租户时发布一个新令牌。谢谢@lucbas我最终在单个“当前选定租户”的上下文中构建了我的应用程序,然后在用户更改租户时发布了一个新令牌,我对结果感到满意。