我只想谈谈我的问题。我已经研究了很多文件,但我找不到任何解决方案。
我只是尝试使用django-tenants。一切正常。但如果任何用户在登录后获得令牌,该令牌对所有租户都有效。
这是一个很大的安全漏洞。
我一直在想一个主意SIGNING_KEY。如果我可以改变每个租户的SIGNING_KEY,它可能是固定的。但事实并非如此。
class TenantJWTAuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
tenant = Client.objects.get(schema_name=connection.schema_name)
jwt_secret_key = tenant.jwt_secret_key
settings.SIMPLE_JWT['SIGNING_KEY'] = jwt_secret_key
这是我的中间件更改每个租户的SIGNING_KEY。
class Client(TenantMixin):
name = models.CharField(max_length=100)
paid_until = models.DateField()
on_trial = models.BooleanField()
created_on = models.DateField(auto_now_add=True)
jwt_secret_key = models.CharField(max_length=100, null=True, blank=True)
# default true, schema will be automatically created and synced when it is saved
auto_create_schema = True
class Domain(DomainMixin):
pass
这是我的模型。
因此,我将jwt_secret_key
添加到我的模型中,并在Middleware中获取此字段,并尝试为jwt设置SIGNING_KEY。但是,用户登录后的jwt仍然可以用于所有租户。
有人知道我的问题吗?对我的解决方案有什么建议或修正吗?
谢谢.
1条答案
按热度按时间mbjcgjjk1#
通过创建一个自定义序列化器,继承djangorestframework-simplejwt的
TokenObtainPairSerializer
,并在get_token
函数中传递额外的数据,可以基于db连接将模式数据传递给jwt令牌。然后可以在从TokenObtainPairView
继承的自定义视图中使用此序列化程序。然后使用此视图获取令牌
为了验证这个令牌,你必须为django rest framework创建一个自定义的身份验证类,并将访问令牌
tenant_schema
与当前连接模式(来自另一个租户)进行比较,如果模式不同,不要返回身份验证数据。然后在项目设置中更改
DEFAULT_AUTHENTICATION_CLASSES
我认为您可以使用
jwt_secret_key
字段实现类似的功能,因为您可以像在中间件中使用connection.schema_name
一样获取租户对象,并将任何租户数据添加到令牌中。然而,我认为一个模式名就足够了,没有必要为jwt令牌向租户模型添加额外的字段。