gpt4 book ai didi

asp.net-mvc - 卡住了创建 "security trimmed"html.ActionLink 扩展方法

转载 作者:行者123 更新时间:2023-12-01 01:38:30 26 4
gpt4 key购买 nike

我正在尝试为 MVC 的 htmlHelper 创建扩展方法。
目的是根据 Controller /操作上设置的 AuthorizeAttribute 启用或禁用 ActionLink。
借用MVCSitemap
在 Maarten Balliauw 创建的代码中,我想在决定如何呈现 Action 链接之前针对 Controller / Action 验证用户的权限。
当我尝试获取 MvcHandler 时,我得到一个空值。
Controller / Action 的属性有没有更好的方法?

下面是扩展方法的代码:

public static class HtmlHelperExtensions
{
public static string SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller)
{
//simplified for brevity
if (IsAccessibleToUser(action, controller))
{
return htmlHelper.ActionLink(linkText, action,controller);
}
else
{
return String.Format("<span>{0}</span>",linkText);
}
}

public static bool IsAccessibleToUser(string action, string controller)
{
HttpContext context = HttpContext.Current;

MvcHandler handler = context.Handler as MvcHandler;

IController verifyController =
ControllerBuilder
.Current
.GetControllerFactory()
.CreateController(handler.RequestContext, controller);

object[] controllerAttributes = verifyController.GetType().GetCustomAttributes(typeof(AuthorizeAttribute), true);
object[] actionAttributes = verifyController.GetType().GetMethod(action).GetCustomAttributes(typeof(AuthorizeAttribute), true);

if (controllerAttributes.Length == 0 && actionAttributes.Length == 0)
return true;

IPrincipal principal = handler.RequestContext.HttpContext.User;

string roles = "";
string users = "";
if (controllerAttributes.Length > 0)
{
AuthorizeAttribute attribute = controllerAttributes[0] as AuthorizeAttribute;
roles += attribute.Roles;
users += attribute.Users;
}
if (actionAttributes.Length > 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 false;
}
foreach (string user in usersArray)
{
if (user != "*" && (principal.Identity.Name == "" || principal.Identity.Name != user)) return false;
}
return true;
}

}

最佳答案

这是工作代码:

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;
}
}
}

我不喜欢使用反射,但我无法访问 ControllerTypeCache。

关于asp.net-mvc - 卡住了创建 "security trimmed"html.ActionLink 扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/121000/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com