web-dev-qa-db-fra.com

Stocker / attribuer des rôles d'utilisateurs authentifiés

Je mets à jour un site pour utiliser MVC et je cherche la meilleure façon de configurer l'authentification.

À ce stade, la connexion fonctionne hors d'Active Directory: validation d'un nom d'utilisateur et d'un mot de passe, puis définition du cookie d'authentification.

Comment puis-je stocker les informations de rôle de l'utilisateur au moment de la connexion, afin que mes contrôleurs puissent voir ces rôles lorsque l'utilisateur navigue sur le site?

[Authorize(Roles = "admin")]

Je n'ai aucun problème à obtenir une liste de rôles à partir d'Active Directory. Je ne sais simplement pas où les mettre pour que les contrôleurs les voient.

54
Billy Logan

Lorsque vous authentifiez votre utilisateur, vous générez une nouvelle instance GenericPrincipal. Le constructeur prend un tableau de chaînes qui sont les rôles de l'utilisateur. Maintenant, définissez HttpContext.Current.User égal au principal générique et écrivez le cookie d'authentification, et cela devrait le faire.

6

Les rôles sont ajoutés à IPrincipal du HttpContext. Vous pouvez créer un GenericPrincipal , analyser la liste des rôles dans le constructeur et la définir comme HttpContext.User. Le GenericPrincipal sera alors accessible via User.IsInRole("role") ou l'attribut [Authorize(Roles="role")]

Une façon de procéder (en C #) consiste à ajouter vos rôles en tant que chaîne séparée par des virgules dans le paramètre de données utilisateur lors de la création de votre ticket d'authentification

string roles = "Admin,Member";
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
  1,
  userId,  //user id
  DateTime.Now,
  DateTime.Now.AddMinutes(20),  // expiry
  false,  //do not remember
  roles, 
  "/");
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
                                   FormsAuthentication.Encrypt(authTicket));
Response.Cookies.Add(cookie);

Accédez ensuite à la liste des rôles à partir du ticket d'authentification et créez un GenericPrincipal à partir de votre Global.asax.cs

protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
  HttpCookie authCookie = 
                Context.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null) {
      FormsAuthenticationTicket authTicket = 
                                  FormsAuthentication.Decrypt(authCookie.Value);
      string[] roles = authTicket.UserData.Split(new Char[] { ',' });
      GenericPrincipal userPrincipal =
                       new GenericPrincipal(new GenericIdentity(authTicket.Name),roles);
      Context.User = userPrincipal;
    }
  }
126
David Glenn

Pour ceux d'entre vous qui utilisent MVC 4 ou supérieur, vous devrez suivre les conseils de Jaroslaw Waliszko lors de l'utilisation de la réponse de David Glenn:

"Je l'ai testé dans ASP.NET MVC 4 et je suggère d'utiliser plutôt Application_PostAuthenticateRequest. Sinon, le principal générique sera remplacé." - Jaroslaw Waliszko 7 sept. À 16h18

Ainsi, comme indiqué ci-dessus, tout ce que vous devez faire est de remplacer le nom de la méthode Application_AuthenticateRequest par Application_PostAuthenticateRequest pour que cela fonctionne. A fonctionné à merveille pour moi! Si on me permettait de voter contre Jaroslaw et David, je le ferais.

5
Gareth

Je serais enclin à simplement créer un fournisseur de rôle personnalisé. Exemple ici:

http://www.danharman.net/2011/06/23/asp-net-mvc-3-custom-membership-provider-with-repository-injection/

3
DanH

Pourriez-vous ne pas déposer un gestionnaire de rôles du magasin d'autorisations ou trouver (par exemple sur Codeplex) ou écrire un autre fournisseur de rôle qui fonctionne avec Active Directory pour obtenir les informations sur les groupes?

Cela vous éviterait d'avoir à authentifier l'utilisateur, à obtenir ses rôles, puis à retransmettre ces informations au constructeur, et cela se produirait automatiquement pour vous dans le cadre du cadre.

1
Zhaph - Ben Duguid