У меня есть приложение для нескольких арендаторов со схемой для каждого арендатора. База данных postgres
База данных содержит следующие схемы:
tenant_cf5f3518bd524c3797b884457b374e50
tenant_46255f07079046139f8c0f94290885cd
tenant_620ef0de80f74f95992742e8db4b153f
tenant_6d93b51d61ed4e33a5fb324845a83603
tenant_8e0fd300a3124de29a3070b89f3662ed
...
Я установил TenantId
на IRequest.Items
в async фильтр запросов.
TenantIdFilter.cs
-----------------
var aHasTenant = dto as IHaveTenant;
if (aHasTenant == null) return;
if (hasTenant.TenantId == Guid.Empty)
{
var error = DtoUtils.CreateErrorResponse(req, HttpError.BadRequest("Missing tenant id"));
await res.WriteToResponse(req, error);
}
if (!req.GetSession().IsAuthenticated){
var error = DtoUtils.CreateErrorResponse(req, HttpError.Unauthorized("Unauthorized"));
await res.WriteToResponse(req, error);
req.Items.Remove("TenantId")
}
req.Items.Add("TenantId", hasTenant.TenantId);
...
appHost.GlobalAsyncRequestFilters.Add(new TenantIdFilter().Invoke);
Я настроил AppHost.GetDbConnection()
для получения подключения к клиенту. Это все хорошо работает. Я настроил строку подключения postgres для включения.
var connectionString = AppSettings.GetString('ConnectionString');
if (req.Items.ContainsKey("TenantId")){
var tenantId = (Guid)req.Items["TenantId"];
connectionString = connectionString + ';Search Path=tenant_{tenantId}'
}
return new OrmLiteDbConnectionFactory(connectionString).Open()
...
Проблема возникает, когда я использую атрибуты [Authenticate]
(подозреваю, что то же самое может произойти с атрибутами ролей / разрешений).
[Authenticate]
public class RestrictedDto : IReturnVoid {
}
Похоже, что фильтр [Authenticate]
вызывается раньше любого GlobalRequestFilter
. Это означает, что TenantId
не будет установлен на IRequest.Items
. И, таким образом, GetDbConnection(IRequest request)
извлечет недействительный IDbConnection
(не будет принимать TenantId
, поскольку он еще не существует).
Когда фильтр Authenticate
пытается извлечь информацию о сеансе из ICacheClient
, ICacheClient
(OrmLiteCacheClient
) извлекает DbConnection
из AppHost.GetDbConnection()
. Затем выдает ошибку, что таблица cache_entry
не найдена.
Я хочу, чтобы TenantIdFilter.cs
был запущен перед любым атрибутом [Authenticate]
. Как я могу это сделать?
Возможно, есть способ, который я мог бы переопределить в AppHost
?