2011-03-29 9 views
5

Tamam, siteme ActionLink yöntemi aracılığıyla biraz güvenlik eklemek istiyorum. Kullanıcı eylem/denetleyiciye erişmek için yeterli haklara sahipse, ActionLink bu bağlantıyı oluşturmalıdır. Değilse, boş bir dize döndürmelidir. Şimdi, ActionLink statik bir yöntemdir ve bu onu daha da zorlaştırır. Yapmaya çalıştığım şeyi başarmanın bir yolu var mı?ActionLink davranışını nasıl geçersiz kılar?

+0

Yetkili eğer bulmaktan kirli işlerini

public static MvcHtmlString AuthorizeActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes) { if (HasActionPermission(helper, actionName, controllerName)) return helper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes); return MvcHtmlString.Empty; } public static MvcHtmlString AuthorizeActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) { if (HasActionPermission(helper, actionName, controllerName)) return helper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes); return MvcHtmlString.Empty; } 

yöntemleri. Kullanıcı, bağlantının ne olduğunu anlayabiliyorsa, doğrudan girebilir. Bağlantının gizlenmesi yapmak için ekstra bir şey olabilir, ancak gerçek güvenliğiniz sunucuda yer almalıdır. –

+0

Evet, bunu yaptım, hepsi kablolandığında harika. Bazı kodları kazacağım ... – hunter

+2

@Matt, düzgün bir şekilde yapıldığında doğru değil. Bağlantıyı oluşturmadan önce sınıf/yöntemden 'Authorize' özniteliğini sorgulayan ActionLinks oluşturabilirsiniz. Böylece, bağlantının görünürlüğünü ve yönteme erişimi Yetkilendirme özniteliğinden başka bir şeyle kontrol edebilirsiniz. – hunter

cevap

8

yeni AuthorizeActionLink uzantı yöntemi. Gerektiğinde aşırı yük. Kullanıcı çok iyi bir güvenlik değil Yani

static bool HasActionPermission(this HtmlHelper htmlHelper, string actionName, string controllerName) 
{ 
    ControllerBase controllerToLinkTo = string.IsNullOrEmpty(controllerName) 
     ? htmlHelper.ViewContext.Controller 
     : GetControllerByName(htmlHelper, controllerName); 

    ControllerContext controllerContext = new ControllerContext(htmlHelper.ViewContext.RequestContext, controllerToLinkTo); 
    ReflectedControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerToLinkTo.GetType()); 
    ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName); 

    return ActionIsAuthorized(controllerContext, actionDescriptor); 
} 

static bool ActionIsAuthorized(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 
{ 
    if (actionDescriptor == null) 
     return false; 

    AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor); 
    foreach (IAuthorizationFilter authFilter in actionDescriptor.GetFilters().AuthorizationFilters) 
    { 
     authFilter.OnAuthorization(authContext); 

     if (authContext.Result != null) 
      return false; 
    } 

    return true; 
} 

static ControllerBase GetControllerByName(HtmlHelper helper, string controllerName) 
{ 
    IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory(); 

    IController controller = factory.CreateController(helper.ViewContext.RequestContext, controllerName); 

    if (controller == null) 
    { 
     throw new InvalidOperationException(
      string.Format(
       CultureInfo.CurrentUICulture, 
       "Controller factory {0} controller {1} returned null", 
       factory.GetType(), 
       controllerName)); 
    } 

    return (ControllerBase)controller; 
} 
+0

Yani aynı Html.ActionLink() yöntemiyle bunu yapmanın bir yolu yok mu? –

+0

hayır, ama bence bu, tüm uygulama genelinde bu tür bir koşullu bağlantı görüntüsü yapmak için harika bir yoldur – hunter

+0

tamam o zaman :) teşekkürler –