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: }
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.
Link do poprzedniego postu nie działa.
TeeeX,
Dzięki, poprawione.