2017-09-21 1 views
0

Dans une application ASP.NET Core MVC, nous utilisons des exigences de stratégie pour l'autorisation qui sont définies à l'aide des rôles de base de données SQL Server. Nous lançons un appel sp_helprolemember {roleName} puis vérifier si l'utilisateur est membre de déterminer si elles passent l'exigence, par exemple gestionnaire du RequirementHandler:Conditions de mise en cache requises ASP.NET Core

// Get Role Members 
IEnumerable<RoleMember> roleMembers = _roleMemberRepository.GetAllByRole(_roleName); 
SecurityIdentifier userSid = new SecurityIdentifier(context.User.Claims.Where(c => c.Type == ClaimTypes.PrimarySid).SingleOrDefault().Value); 

if (roleMembers.Any(rm => new SecurityIdentifier(rm.MemberSID, 0) == userSid)) 
{ 
    context.Succeed(requirement); 
} 

MemberSID est une colonne de tableau byte[] de sp_helprolemember

Cela fonctionne, mais mon Le souci est d'interroger la base de données chaque fois que nous avons besoin de gérer une exigence, qui, basée sur un code déjà écrit peut être plusieurs fois dans une vue.

Est-il préférable de mettre ces données en cache dans la mémoire pour minimiser les requêtes de la base de données? J'ai eu l'idée d'utiliser la mise en cache en mémoire pour chaque gestionnaire d'exigences afin de garder une trace des utilisateurs précédemment autorisés et de lui donner une fenêtre glissante de quelques minutes avant de les effacer, mais je n'ai jamais travaillé avec Je me demandais s'il y avait une pratique standard pour faire quelque chose comme ça.

+0

Est-ce que 'GetAllByRole' renvoie tous les membres dans le nom de rôle donné? – Win

+0

Oui, il appelle simplement la procédure stockée système SQL Server sp_helprolemember avec le nom de rôle fourni. – Valuator

+0

Pourrait-il être des milliers de lignes en fonction du nombre de membres assignés à la rolename? Souhaitez-vous connaître l'approche alternative qui pourrait nécessiter certaines modifications dans votre code existant? – Win

Répondre

1

Afin d'éviter l'accès à la base de données à chaque requête, nous enregistrons normalement le rôle de nom d'utilisateur autorisé en tant que revendication de rôle dans Principal. Il crypte essentiellement ces revendications et les enregistre dans un cookie.

// Login 
var claims = new List<Claim> 
{ 
    new Claim(ClaimTypes.Sid, user.Id.ToString()), 
    new Claim(ClaimTypes.Name, user.UserName), 
    new Claim(ClaimTypes.GivenName, user.FirstName), 
    new Claim(ClaimTypes.Surname, user.LastName) 
};  
foreach (string roleName in authorizedRoleName) 
{ 
    claims.Add(new Claim(ClaimTypes.Role, roleName)); 
} 
var identity = new ClaimsIdentity(claims, "local", "name", "role"); 
var principal = new ClaimsPrincipal(identity); 

// Usage 
if(context.User.HasClaim(ClaimTypes.Role, _roleName)) 
    context.Succeed(requirement); 
+0

Quel est le cycle de vie de cela? Dites si quelqu'un supprime ou ajoute un utilisateur à un rôle dans la base de données. – Valuator

+0

Si vous souhaitez valider les informations d'identification, vous devez accéder à la base de données à chaque demande. Vous pouvez en lire plus sur [Réagir aux modifications back-end] (https://docs.microsoft.com/fr-fr/aspnet/core/security/authentication/cookie?tabs=aspnetcore2x#reacting-to-back-end- changements). – Win

+0

Existe-t-il un endroit où les revendications peuvent être ajoutées lors de l'utilisation de l'authentification Windows? J'ai essayé d'ajouter des revendications comme ci-dessus en utilisant ClaimsTransformer et en définissant des rôles, puis en vérifiant la revendication dans mon RequirementHandler, mais le code de ClaimsTransformer a fini par être exécuté plus souvent que le code RequirementHandler, donc je n'ai rien gagné. – Valuator