2010-02-22 3 views
1

J'expérimente des liens d'action limités par la sécurité dans ASP.NET MVC et envisage d'utiliser la méthode auxiliaire SecurityTrimmedActionLinkdescribed here (avec quelques modifications).Comment séparer visuellement les liens d'action sécurisés dans ASP.NET MVC

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Security.Principal; 
using System.Web.Routing; 
using System.Web.Mvc; 
using System.Collections; 
using System.Reflection; 
namespace System.Web.Mvc.Html 
{ 
    public static class HtmlHelperExtensions 
    { 
     public static string SecurityTrimmedActionLink(
     this HtmlHelper htmlHelper, 
     string linkText, 
     string action, 
     string controller) 
     { 
      return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, false); 
     } 
     public static string SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, bool showDisabled) 
     { 
      if (IsAccessibleToUser(action, controller)) 
      { 
       return htmlHelper.ActionLink(linkText, action, controller); 
      } 
      else 
      { 
       return showDisabled ? String.Format("<span>{0}</span>", linkText) : ""; 
      } 
     } 
     public static bool IsAccessibleToUser(string actionAuthorize, string controllerAuthorize) 
     { 
      Assembly assembly = Assembly.GetExecutingAssembly(); 
      GetControllerType(controllerAuthorize); 
      Type controllerType = GetControllerType(controllerAuthorize); 
      var controller = (IController)Activator.CreateInstance(controllerType); 
      ArrayList controllerAttributes = new ArrayList(controller.GetType().GetCustomAttributes(typeof(AuthorizeAttribute), true)); 
      ArrayList actionAttributes = new ArrayList(); 
      MethodInfo[] methods = controller.GetType().GetMethods(); 
      foreach (MethodInfo method in methods) 
      { 
       object[] attributes = method.GetCustomAttributes(typeof(ActionNameAttribute), true); 
       if ((attributes.Length == 0 && method.Name == actionAuthorize) || (attributes.Length > 0 && ((ActionNameAttribute)attributes[0]).Name == actionAuthorize)) 
       { 
        actionAttributes.AddRange(method.GetCustomAttributes(typeof(AuthorizeAttribute), true)); 
       } 
      } 
      if (controllerAttributes.Count == 0 && actionAttributes.Count == 0) 
       return true; 

      IPrincipal principal = HttpContext.Current.User; 
      string roles = ""; 
      string users = ""; 
      if (controllerAttributes.Count > 0) 
      { 
       AuthorizeAttribute attribute = controllerAttributes[0] as AuthorizeAttribute; 
       roles += attribute.Roles; 
       users += attribute.Users; 
      } 
      if (actionAttributes.Count > 0) 
      { 
       AuthorizeAttribute attribute = actionAttributes[0] as AuthorizeAttribute; 
       roles += attribute.Roles; 
       users += attribute.Users; 
      } 

      if (string.IsNullOrEmpty(roles) && string.IsNullOrEmpty(users) && principal.Identity.IsAuthenticated) 
       return true; 

      string[] roleArray = roles.Split(','); 
      string[] usersArray = users.Split(','); 
      foreach (string role in roleArray) 
      { 
       if (role == "*" || principal.IsInRole(role)) 
        return true; 
      } 
      foreach (string user in usersArray) 
      { 
       if (user == "*" && (principal.Identity.Name == user)) 
        return true; 
      } 
      return false; 
     } 

     public static Type GetControllerType(string controllerName) 
     { 
      Assembly assembly = Assembly.GetExecutingAssembly(); 
      foreach (Type type in assembly.GetTypes()) 
      { 
       if (type.BaseType.Name == "Controller" && (type.Name.ToUpper() == (controllerName.ToUpper() + "Controller".ToUpper()))) 
       { 
        return type; 
       } 
      } 
      return null; 
     } 
    } 
} 

Ce que je voudrais faire est de mettre une barre verticale entre chaque lien comme celui-ci:

link1 | link2 | link3 

Mais je ne veux pas deux barres verticales apparaissent entre les liens si un lien a été coupé off (la méthode helper renvoie une chaîne vide), et il ne peut y avoir aucune barre verticale si aucun lien ou un seul lien n'apparaît. La méthode auxiliaire SecurityTrimmedActionLink ne peut pas aider avec les barres verticales; il n'aura aucune connaissance des autres liens.

Est-ce possible avec une logique simple dans la vue?

+0

Le lien vers SecurityTrimmedActionLink est cassé. Y a-t-il une chance que du code décrive comment cela fonctionne? – mutex

+0

Question mise à jour avec le code de http://web.archive.org/web/20081226003615/http://inq.me/post/ASPNet-MVC-Extension-method-to-create-a-Security-Aware-HtmlActionLink .aspx –

+0

Merci +1. Wayback machine, bien sûr! :) – mutex

Répondre

0

Après avoir réfléchi, j'ai créé une nouvelle méthode HtmlHelper:

using System.Text; 

namespace System.Web.Mvc.Html 
{ 
    public static class HtmlHelpers 
    { 
     public static string Delimit(
      this HtmlHelper h, string delimiter, params string[] s) 
     { 
      bool flag = false; 
      StringBuilder b = new StringBuilder(); 
      for (int i = 0; i < s.Length; i++) 
       if (s[i].Length > 0) 
        if (flag) 
         b.Append(delimiter + s[i]); 
        else 
        { 
         flag = true; 
         b.Append(s[i]); 
        } 
      return b.ToString(); 
     } 
    } 
} 

Ce qui devrait me permettre d'écrire:

<% =Html.Delimit("|", 
     Html.SecurityTrimmedActionLink(...), 
     Html.SecurityTrimmedActionLink(...), 
     ... 
    ); 
$> 
Questions connexes