2009-09-28 4 views
3

Je viens à la conclusion que je dois abandonner l'ASP.NET Membership (pour la liste des raisons).Donc très très confus au sujet de l'authentification dans asp.net mvc

Maintenant, la seule chose dont j'ai besoin est de créer un cookie (fait par Form Authentication), des méthodes personnalisées pour l'authentification (terminé) et enfin la validation basée sur si elles sont connectées ou par rôle.

Je suis coincé sur le dernier.

J'essaie de remplacer le Authorize (attribut) mais je n'ai aucune idée de comment faire cela. J'ai regardé de nombreux exemples et chacun semble être fait différemment, puis le suivant. Je ne sais pas pourquoi ils font ça ou celui que je devrais utiliser.

Certains tutoriels semblent faire l'authentification dans le AuthorizeCore, certains le font dans le OnAuthentication.

Certains utilisent une chose AuthorizationContext puis appellent cette classe de base.

base.OnAuthorization(filterContext); 

Certains semblent faire de la mise en cache dedans.

Ce que je veux, c'est toutes les fonctionnalités que les built-in ont, mais juste accroché à mes tables personnalisées. Comme si je devais avoir ma propre table de rôles. Je dois dire où c'est et tirer les choses dans

Aussi je n'ai pas la moindre idée comment faire ou comment décorer l'étiquette comme cette

[Authorize(Roles="test")] 

Références: -. http://darioquintana.com.ar/blogging/tag/aspnet-mvc/ asp.net mvc Adding to the AUTHORIZE attribute http://davidhayden.com/blog/dave/archive/2009/04/09/CustomAuthorizationASPNETMVCFrameworkAuthorizeAttribute.aspx

Modifier

C'est ce que j'ai maintenant.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 
    public sealed class AuthorizeAttributeCustom : AuthorizeAttribute 
    { 

     public string Roles { get; set; } 


     private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus) 
     { 
      validationStatus = OnCacheAuthorization(new HttpContextWrapper(context)); 
     } 

     public override void OnAuthorization(AuthorizationContext filterContext) 
     { 

      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
      { 
       // auth failed, redirect to login page 
       filterContext.Result = new HttpUnauthorizedResult(); 
       return; 
      } 

      DataClasses1DataContext test = new DataClasses1DataContext(); 
      var name = filterContext.HttpContext.User.Identity.Name; 
      var user = test.User2s.Where(u => u.userName == name).FirstOrDefault(); 
      var role = test.Roles.Where(u => u.UserId == user.userId).Select(u => u.Role1).FirstOrDefault(); 

      string[] split = Roles.Split(','); 

      if (split.Contains(role) == true) 
      { 
       // is authenticated and is in the required role 
       SetCachePolicy(filterContext); 
       return; 
      } 
      filterContext.Result = new HttpUnauthorizedResult(); 
     } 

     private void SetCachePolicy(AuthorizationContext filterContext) 
     { 
      // ** IMPORTANT ** 
      // Since we're performing authorization at the action level, the authorization code runs 
      // after the output caching module. In the worst case this could allow an authorized user 
      // to cause the page to be cached, then an unauthorized user would later be served the 
      // cached page. We work around this by telling proxies not to cache the sensitive page, 
      // then we hook our custom authorization code into the caching mechanism so that we have 
      // the final say on whether a page should be served from the cache. 
      HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache; 
      cachePolicy.SetProxyMaxAge(new TimeSpan(0)); 
      cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */); 
     } 
    } 

Out Questions Debout

  1. Pourquoi est-il scellé? Si elle est scellée cela ne rend-il pas plus difficile à l'unité test?
  2. Qu'est-ce que filterContext?
  3. Pourquoi AuthorizeCore n'est-il pas utilisé? Seulement OnAuthentication?
  4. À quoi sert le cache? Comme cache-t-il le rôle? Ou la page? Je ne peux pas dire avec le débogueur semble exécuter le code chaque fois fois.

  5. La mise en cache est-elle sécurisée?

  6. En général est ce coffre-fort (sans trous dans à être un peu inquiet explioted- je vis quelque chose et ont un trou majeur dans mon site).

Répondre

2

Voici un attribut personnalisé qui fonctionnerait comme vous le souhaitez; en utilisant un Enum pour les types de rôle et en utilisant la création de cookie vous-même, ce qui permet de stocker des rôles.

utilisation

[AuthorizeAttributeCustom(RoleRequired = GoodRoles.YourRoleTypeHere)] 

code d'attribut:

//http://stackoverflow.com/questions/977071/redirecting-unauthorized-controller-in-asp-net-mvc/977112#977112 
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 
    public sealed class AuthorizeAttributeCustom : AuthorizeAttribute 
    { 

     /// <summary> 
     /// The name of the view to render on authorization failure. Default is "Error". 
     /// </summary> 
     public string ViewName { get; set; } 
     public ViewDataDictionary ViewDataDictionary { get; set; } 
     public DeniedAccessView DeniedAccessView { get; set; } 

     private GoodRoles roleRequired = GoodRoles.None; 
     public GoodRoles RoleRequired { get{ return roleRequired;} set{ roleRequired = value;} } // this may evolve into sets and intersections with an array but KISS 

     public AuthorizeAttributeCustom() 
     { 
      ViewName = "DeniedAccess"; 
      DeniedAccessView = new DeniedAccessView 
            { 
             FriendlyName = "n/a", 
             Message = "You do not have sufficient privileges for this operation." 
            }; 
      ViewDataDictionary = new ViewDataDictionary(DeniedAccessView); 
     } 

     private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus) 
     { 
      validationStatus = OnCacheAuthorization(new HttpContextWrapper(context)); 
     } 


     public override void OnAuthorization(AuthorizationContext filterContext) 
     { 

      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
      { 
       // auth failed, redirect to login page 
       filterContext.Result = new HttpUnauthorizedResult(); 
       return; 
      } 

      if (RoleRequired == GoodRoles.None || filterContext.HttpContext.User.IsInRole(RoleRequired.ToString())) 
      { 
       // is authenticated and is in the required role 
       SetCachePolicy(filterContext); 
       return; 
      } 

      filterContext.Result = new ViewResult { ViewName = ViewName, ViewData = ViewDataDictionary }; 
     } 

     private void SetCachePolicy(AuthorizationContext filterContext) 
     { 
      // ** IMPORTANT ** 
      // Since we're performing authorization at the action level, the authorization code runs 
      // after the output caching module. In the worst case this could allow an authorized user 
      // to cause the page to be cached, then an unauthorized user would later be served the 
      // cached page. We work around this by telling proxies not to cache the sensitive page, 
      // then we hook our custom authorization code into the caching mechanism so that we have 
      // the final say on whether a page should be served from the cache. 
      HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache; 
      cachePolicy.SetProxyMaxAge(new TimeSpan(0)); 
      cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */); 
     } 


    } 

vous aurez besoin d'avoir explicitement ajouté vos rôles auth cookie et les relire dans un contrôleur de base dit. ma mise en œuvre a d'autres détails que vous pourriez ne pas vouloir, alors peut-être mieux de lire ici: http://ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html

+0

Pouvez-vous expliquer cela un peu? Comme à quoi sert le chache? ceci pour la page ou juste les rôles? A quoi sert filterContext? – chobo2

+0

Je suis aussi en train de passer par enum le seul moyen? Je ne peux pas le faire ressembler à ceux intégrés? Puisque je ne suis pas sûr de savoir comment cela va affecter les tests unitaires? En ce moment je regarde si la balise est là et vérifie ce qu'ils contiennent. Si elle contient les rôles que j'attends, alors ça passe. Aussi, je remarque qu'il n'utilise pas la méthode AuthorizeCore non plus. Pourquoi pas? – chobo2

+0

également la façon dont il est en ce moment cette ligne "filterContext.HttpContext.User.IsInRole (RoleRequired.ToString())" où est ce qui tire le rôle de? VS2008 Intellisense n'a même pas quelque chose pour IsInRole. J'aurais pensé que je devrais le faire avec une demande de base de données. – chobo2

Questions connexes