【发布时间】:2014-11-04 12:59:08
【问题描述】:
我想根据用户的授权显示/隐藏编辑/删除链接(包括菜单项)。我已经实现了 AuthorizeAttribute 并为角色检查重写的 AuthorizeCore 提供了自定义逻辑。在检查用户是否有权查看 LinkExtensions 方法中的编辑/删除链接时,我想使用该逻辑。 这是我的设置:
public class AuthorizeActivity : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
}
protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
{
bool isAuthorized = base.AuthorizeCore(httpContext);
string actionType = httpContext.Request.HttpMethod;
string controller = httpContext.Request.RequestContext.RouteData.Values["controller"].ToString();
string action = httpContext.Request.RequestContext.RouteData.Values["action"].ToString();
//ADMINS
if (controller == "Admin")
{
if (httpContext.User.IsInRole(Constants.Admin))
return true;
}
else
{
//DATA READERS ONLY
if ((action == "Details") || (action == "Index"))
{
if (httpContext.User.IsInRole(Constants.DataReader))
return true;
}
//DATA WRITERS & IT
else
{
...
}
}
return false;
}
我还使用了 Vivien Chevallier 的逻辑来创建此处概述的授权操作链接扩展:http://vivien-chevallier.com/Articles/create-an-authorized-action-link-extension-for-aspnet-mvc-3 现在在我看来我可以使用:
<li>@Html.ActionLinkAuthorized("Admin", "Index", "Admin",false) </li>
链接是否显示取决于用户的权限。 在我的控制器中,动作装饰有:
[AuthorizeActivity]
public ActionResult Index()
{
return View(view);
}
除非我在我认为多余的属性中指定“角色”,否则授权链接将不起作用,如下所示:
[AuthorizeActivity(Roles = Constants.roleSalesContractAdmin)]
public ActionResult Index()
{
return View(view);
}
我似乎无法找到重用 AuthorizeAttribute 中的逻辑的方法。理想情况下,它会像 Vivien 一样在 ActionLinkAuthorized 中调用:
public static MvcHtmlString ActionLinkAuthorized(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes, bool showActionLinkAsDisabled)
{
if (htmlHelper.ActionAuthorized(actionName, controllerName)) //The call to verify here -- or inside ActionAuthorized
{
return htmlHelper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);
}
else
{
if (showActionLinkAsDisabled)
{
TagBuilder tagBuilder = new TagBuilder("span");
tagBuilder.InnerHtml = linkText;
return MvcHtmlString.Create(tagBuilder.ToString());
}
else
{
return MvcHtmlString.Empty;
}
}
}
这是 ActionAuthorized 方法。 OnAuthorization 调用不会转到自定义的
public static bool ActionAuthorized(this HtmlHelper htmlHelper, string actionName, string controllerName)
{
ControllerBase controllerBase = string.IsNullOrEmpty(controllerName) ? htmlHelper.ViewContext.Controller : htmlHelper.GetControllerByName(controllerName);
ControllerContext controllerContext = new ControllerContext(htmlHelper.ViewContext.RequestContext, controllerBase);
ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerContext.Controller.GetType());
ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
if (actionDescriptor == null)
return false;
FilterInfo filters = new FilterInfo(FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor));
AuthorizationContext authorizationContext = new AuthorizationContext(controllerContext, actionDescriptor);
foreach (IAuthorizationFilter authorizationFilter in filters.AuthorizationFilters)
{
authorizationFilter.OnAuthorization(authorizationContext); //This call
if (authorizationContext.Result != null)
return false;
}
return true;
}
【问题讨论】:
-
你应该看看我的anwsear,能给你一个想法:stackoverflow.com/questions/18874081/…
-
为什么不将自定义 Authorization 属性的 AuthorizeCore 中的逻辑提取到静态方法中,放入某个静态类并在属性和帮助器中重用它?
标签: c# asp.net asp.net-mvc asp.net-mvc-4 authorization