我有一个基于策略的.net核心MVC应用程序,其中只有授权用户可以访问任何特定菜单。我为每个控制器都使用了[Authorize(Policy = "MenuName")]
属性。但是我想用一个Enum
来概括它,其中所有菜单都列在一个Enum
中,并用在Authorize
属性中,而不是静态字符串("MenuName"
)中。
public enum MenuEnum
{
[Description("Menu1")]
Dashboard,
[Description("Menu2")]
Help,
[Description("Menu3")]
About
}
,我想像[Authorize(Policy = MenuEnum.Dashboard)]
那样使用它,而不是静态字符串[Authorize(Policy = "Dashboard")]
。我们可以用任何方法用Enum来概括Authorize
属性吗?
答案 0 :(得分:1)
我有一个扩展方法,我用它来读取显示属性的名称
public static string ToDisplay(this Enum value, DisplayProperty property = DisplayProperty.Name)
{
var attribute = value.GetType().GetField(value.ToString())
.GetCustomAttributes<DisplayAttribute>(false).FirstOrDefault();
if (attribute == null)
return value.ToString();
var propValue = attribute.GetType().GetProperty(property.ToString()).GetValue(attribute, null);
return propValue.ToString();
}
您可以通过这种方式使用它 用DisplayAttribute替换Description属性并设置属性名称
public enum MenuEnum
{
[Display(Name="Menu1")]
Dashboard,
[Display(Name="Menu2")]
Help,
[Display(Name="Menu3")]
About
}
[Authorize(Policy=MenuEnum.About.ToDisplay())]
答案 1 :(得分:1)
您可以实现自己的AuthorizeAttribute。
1.AuthorizeMenuPolicyAttribute
public class AuthorizeMenuPolicyAttribute : TypeFilterAttribute
{
public AuthorizeMenuPolicyAttribute(MenuEnum Policy) : base(typeof(AuthorizeMenuPolicyFilter))
{
Arguments = new object[] { Policy };
}
}
2.AuthorizeMenuPolicyFilter
public class AuthorizeMenuPolicyFilter: IAsyncAuthorizationFilter
{
private readonly IAuthorizationService _authorization;
public MenuEnum _policy { get; set; }
public AuthorizeMenuPolicyFilter(MenuEnum policy, IAuthorizationService authorization)
{
_policy = policy;
_authorization = authorization;
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
string description = GetEnumDescription(_policy);
var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, description);
if (authorized.Succeeded)
{
return;
}
context.Result = new ForbidResult();
return;
}
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
if (attributes != null && attributes.Any())
{
return attributes.First().Description;
}
return value.ToString();
}
}
3。在启动时添加所需的策略
services.AddAuthorization(options =>
{
options.AddPolicy("Menu1", policy =>
policy.RequireAssertion(context =>
context.User.HasClaim(c => c.Type == "menu1")));
});
4。基于枚举中的字符串值进行授权
[AuthorizeMenuPolicy(MenuEnum.Dashboard)]