Je suis this tutorial afin d'utiliser la sécurité au niveau de la ligne dans SQL Server via Entity Framework 6 CodeFirst. L'exemple de code tutoriel montre comment utiliser IDbConnectionInterceptor et définir l'ID utilisateur actuel dans session_context
. Pour récupérer l'ID utilisateur, il utilise la méthode d'accès statique HttpContext.Current.User.Identity.GetUserId()
qui est couplée avec l'identité Asp.Net et l'espace de noms System.Web.Entity Framework - Définition de session_context à l'aide de IDbConnectionInterceptor
Dans mon application web multi-locataire, je voulais avoir le TenantID injecté dans le DbConnectionInterceptor
avec Unity (sans créer dur couplage avec HttpContext
) et régler la TenantID dans le session_context
. J'ai découvert que le DbConnectionInterceptor
doit être enregistré globalement (par exemple au démarrage de l'application) et par conséquent vous ne pouvez pas créer une instance DbConnectionInterceptor
par requête.
J'ai également 2 DbContexts dans ma solution représentant 2 bases de données différentes (base de données de locataire et une base de données système) et je veux seulement appliquer session_context
à la base de données de locataire seulement.
Il semble que la seule option qui me reste est d'avoir le TenantID injecté dans le DbContext
isntance par l'unité et accéder à l'instance DbContext
dans la méthode Opened()
du DbConnectionInterceptor
. Pour ce faire j'ai pensé utiliser le paramètre interceptionContext
dans la méthode Opened()
. interceptionContext
a une propriété DbContexts
(pluriel). Il n'y a pas de documentation sur ce donc je suppose quelque chose comme ça fonctionnerait:
public void Opened(DbConnection connection, DbConnectionInterceptionContext interceptionContext)
{
var firstDbContext = interceptionContext.DbContexts.FirstOrDefault(d => d is TenantDataContext);
if (firstDbContext != null)
{
var dataContext = firstDbContext as TenantDataContext;
var tenantId = dataContext.TenantId;
DbCommand cmd = connection.CreateCommand();
cmd.CommandText = $"EXEC sp_set_session_context @key=N'TenantId', @value={tenantId};";
cmd.ExecuteNonQuery();
}
}
Mes code vérifie si la collection DbContexts contient le TenantDataContext
comme premier élément et exécute la sp_set_session_context
. Mais ce qui m'inquiète, c'est de savoir s'il y a une chance que DbContexts soit là en même temps? Si tel était le cas, la connexion à mon autre base de données définirait également le session_context
dont je n'ai pas besoin. Je me demande pourquoi Microsoft a fourni cela comme une propriété de collection plutôt qu'une seule propriété DbContext
. Cette propriété vous permet de vous demander si la même connexion peut être utilisée par plusieurs DbContexts.
Y at-il quelqu'un qui a réalisé ce que je veux? Toute explication sur interceptionContext serait également utile pour moi.
Je suis confronté au même problème. Avez-vous déjà compris cela? – stoneMaster
Malheureusement non. Mon code est toujours le même. Nous ne sommes pas encore allés en production, mais jusqu'à présent, nous n'avons pas rencontré de problème visible avec cela. – ravinsp