devstyle.pl - Blog dla każdego programisty
devstyle.pl - Blog dla każdego programisty
2 minut

Ukrywanie linków dla nieautoryzowanych użytkowników


25.07.2011

Ostatnio pokazałem jak dobrać się do typu kontrolera dla dowolnego żądania. Było mi to potrzebne do wykonania zadania, które okazało się dużo bardziej skomplikowane niż początkowo zakładałem.

Chciałem mianowicie być w stanie zrobić takie coś:

  1:  <% if (MVC.Administration.Users.DisableUser().IsUserAuthorized(this.ViewContext.RequestContext)) { %>
  2:      <a href="#" data-role="disable-user">Disable user</a>
  3:  <% } %>

Czyli: w dowolnym miejscu (w tym przypadku – w widoku) sprawdzić, czy aktualny użytkownik ma uprawnienia do wykonania akcji pod danym URLem (ta fajna, silnie typowana notacja dzięki T4MVC). Bo po co go wyświetlać skoro i tak nie może go użyć? (można to oczywiście zamknąć w jakimś helperze)

Kod metody IsUserAuthorized przedstawia się następująco:

  1:  public static class ActionResultExtensions
  2:  {
  3:      public static bool IsUserAuthorized(this ActionResult @this, RequestContext requestContext)
  4:      {
  5:          string controllerName = (string)@this.GetRouteValueDictionary()["Controller"];
  6:          string actionName = (string)@this.GetRouteValueDictionary()["Action"];
  7:  
  8:          Type controllerType = ControllerTypeLocator.FindControllerType(
  9:              requestContext, controllerName
 10:          );
 11:  
 12:          var controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
 13:  
 14:          var controllerLevelAuthorization = controllerDescriptor
 15:              .GetCustomAttributes(true).OfType<AuthorizeAttribute>();
 16:  
 17:          var actionsDescriptors = controllerDescriptor.GetCanonicalActions
 18:              ().Where(x => x.ActionName == actionName);
 19:  
 20:          var actionLevelAuthorization = actionsDescriptors
 21:              .SelectMany(x => x.GetCustomAttributes(true).OfType<AuthorizeAttribute>());
 22:  
 23:          bool isAuthorized = controllerLevelAuthorization.Concat(actionLevelAuthorization)
 24:              .Select(x => new OpenAuthorizeAttribute(x))
 25:              .All(x => x.Authorized(requestContext));
 26:  
 27:          return isAuthorized;
 28:      }
 29:  }

Wykorzystany wyżej OpenAuthorizeAttribute pochodzi z projektu MvcContrib. A ControllerTypeLocator przedstawiłem poprzednim poście.

No i na koniec wspomniany helper generujący linki dla autoryzowanych użytkowników:

  1:  public static MvcHtmlString ActionLinkIfAuthorized(this HtmlHelper @this, string linkText, ActionResult actionResult, string format, object linkAttributes)
  2:  {
  3:      if (actionResult.IsUserAuthorized(@this.ViewContext.RequestContext) == false)
  4:      {
  5:          return MvcHtmlString.Empty;
  6:      }
  7:  
  8:      var a = @this.ActionLink(linkText, actionResult, linkAttributes);
  9:  
 10:      if (format.HasNoText())
 11:      {
 12:          return a;
 13:      }
 14:  
 15:      return MvcHtmlString.Create(format.FormatWith(a.ToString()));
 16:  }

Nie przegap kolejnych postów!

Dołącz do ponad 9000 programistów w devstyle newsletter!

Tym samym wyrażasz zgodę na otrzymanie informacji marketingowych z devstyle.pl (doh...). Powered by ConvertKit
Notify of
Gutek

to ja jeszcze dam linka do tego:
http://www.vivienchevallier.com/Articles/create-an-authorized-action-link-extension-for-aspnet-mvc-3

AuthorizedActionLink extension do HtmlHelper z mozliwoscia wypisania ciagu znakow jak osoba nie ma dostepu.

TeeeX
TeeeX

Link do poprzedniego postu nie działa.

procent

TeeeX,
Dzięki, poprawione.

Moja książka

Facebook

Zobacz również