如何获得在ASP.NET MVC 4控制器操作自定义注解的属性? [英] How to get custom annotation attributes for a controller action in ASP.NET MVC 4?

查看:112
本文介绍了如何获得在ASP.NET MVC 4控制器操作自定义注解的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我跟我的ASP.NET MVC应用程序基于权限的授权系统的工作。
为此,我创建了一个自定义的授权属性。

I am working with a permission based authorization system for my app in ASP.NET MVC. For this I have created a custom authorization attribute

public class MyAuthorizationAttribute : AuthorizeAttribute
{
    string Roles {get; set;}
    string Permission {get; set;}
}

,这样我可以授权由双方角色或注释的操作,如

so that I can authorize a user by both role or a specific permission key with annotation for actions like

public class UserController : Controller
{
    [MyAuthorization(Roles="ADMIN", Permissions="USER_ADD")]
    public ActionResult Add()

    [MyAuthorization(Roles="ADMIN", Permissions="USER_EDIT")]
    public ActionResult Edit()

    [MyAuthorization(Roles="ADMIN", Permissions="USER_DELETE")]
    public ActionResult Delete()
}

然后我重写AuthorizeCore()方法,在具有类似的逻辑(伪code)

then I override AuthorizeCore() method in MyAuthorizationAttribute class with similar logic(pseudo code)

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    if(user not authenticated)
        return false;

    if(user has any role of Roles)
        return true;

    if(user has any permission of Permissions)
        return true;

    return false;
}

截至本是工作的罚款。

Up to this is working fine.

现在我需要某种形式的扩展方法,这样我可以动态地查看页面,将返回基于MyAuthorization属性授权逻辑操作URL给定动作产生动作的URL。像

Now I need some sort of extension methods so that I can dynamically generate action url in view pages that will return action url based on MyAuthorization attribute authorization logic for the given action. Like

@Url.MyAuthorizedAction("Add", "User")

将返回链接到用户/添加,如果用户具有管理员角色或拥​​有USER_ADD(如在动作属性定义)的许可或以其他方式返回空字符串。

will return url to "User/Add" if user has admin role or has permission of "USER_ADD" (as defined in attributes for the action) or return empty string otherwise.

但在互联网的几天后,搜索我想不出来。 (

But after searching in internet for few days I could not figure it out. :(

到目前为止,我只发现了这"安全意识"操作链接?运作在执行所有操作筛选器的动作,直到它失败。

So far I have found only this "Security aware" action link? which works by executing all action filters for the action until it fails.

这是不错的,但我认为这将是执行所有的操作筛选每个我所说的MyAuthorizedAction()方法的时间开销。另外它也没有跟我的版本(MVC 4和.NET 4.5)工作

It's nice, but I think it would be an overhead to execute all the action filters for each time I call the MyAuthorizedAction() method. Besides It also didn't work with my version (MVC 4 and .NET 4.5)

什么我需要的是检查身份验证的用户的角色,权限(将存储在会议)在针对给定的动作授权的角色和权限。喜欢的东西如下(伪code)

What all I need is to check authenticated user's role, permissions (will be stored in session) against authorized role and permission for the given action. Like something as following (pseudo code)

MyAuthorizedAction(string actionName, string controllerName)
{
    ActionObject action = SomeUnknownClass.getAction(actionName, controllerName)
    MyAuthorizationAttribute attr = action.returnsAnnationAttributes()

    if(user roles contains any in attr.Roles 
       or 
       user permissions contains any attr.Permissions)
    {
        return url to action
    }
    return empty string
}

我正在寻找获得了相当长的时间action属性值,都找不到足够好的资源的解决方案。我失去了正确的关键字? :/

I am searching the solution of getting action attributes value for quite a long time, could not find enough good resources at all. Am I missing out right keywords? :/

如果任何人都可以向我提供的解决方案,这将是真正有很大的帮助。
预先感谢解决方案

If anyone can provide me the solution that would be truly a great help. Thanks in advance for the solutions

推荐答案

虽然我同意,根据权限生成URL可能不是最好的做法,如果你想继续反正你可以找到的操作和使用这些它们的属性:

While I agree that generating urls based on permissions is probably not best practices, if you want to continue anyway you can find the actions and their attributes using these:

找回操作的方法:
此检索方法的相关信息的集合,因为它可以有多个控制器的类具有相同的名称,并在特定的同名多个方法与使用的区域。如果你担心这个,我会离开歧给你。

Retrieve 'Action' methods: This retrieves a collection of method infos because it is possible to have multiple Controller classes with the same name and multiple methods of the same name in particular with the use of areas. If you have to worry about this I'll leave the disambiguation up to you.

public static IEnumerable<MethodInfo> GetActions(string controller, string action)
{
    return Assembly.GetExecutingAssembly().GetTypes()
           .Where(t =>(t.Name == controller && typeof(Controller).IsAssignableFrom(t)))
           .SelectMany(
                type =>
                type.GetMethods(BindingFlags.Public | BindingFlags.Instance)
                    .Where(a => a.Name == action && a.ReturnType == typeof(ActionResult))
             );

}

从MyAuthorizationAttributes权限:

public static MyAuthorizations GetMyAuthorizations(IEnumerable<MethodInfo> actions)
{
    var myAuthorization = new MyAuthorizations();
    foreach (var methodInfo in actions)
    {
        var authorizationAttributes =  methodInfo
                .GetCustomAttributes(typeof (MyAuthorizationAttribute), false)
                .Cast<MyAuthorizationAttribute>();
        foreach (var myAuthorizationAttribute in authorizationAttributes)
        {
            myAuthorization.Roles.Add(MyAuthorizationAttribute.Role);
            myAuthorization.Permissions.Add(MyAuthorizationAttribute.Permission);
        }
    }
    return myAuthorization;
}
public class MyAuthorizations
{
    public MyAuthorizations()
    {
        Roles = new List<string>();
        Permissions = new List<string>();
    }
    public List<string> Roles { get; set; }
    public List<string> Permissions { get; set; }
}

最后AuthorizedAction扩展:警告:如果你有一个给定的控制器/动作对这样会给'授权'的网址,如果用户将有权使用其中的任何一个以上的比赛。 ..

Finally the AuthorizedAction extension: warning:If you do have more than one match for a given controller/action pair this will give the 'authorized' url if the user is authorized for any of them...

public static string AuthorizedAction(this UrlHelper url, string controller, string action)
{
    var actions = GetActions(controller, action);
    var authorized = GetMyAuthorizations(actions);
    if(user.Roles.Any(userrole => authorized.Roles.Any(role => role == userrole)) ||
       user.Permissions.Any(userPermission => authorized.Permissions.Any(permission => permission == userPermission)))
    {
        return url.Action(controller,action)
    }
    return string.empty;
}

基于权限的生成URL A注:结果
我声明这是的可能的不是最好的,因为很多小事的做法。根据您的情况可能每一个都有自己的相关性水平。

A Note on Generating Urls Based on Permissions:
I state this is probably not best practice because of many little things. Each may have their own level of relevance depending on your situation.


  • 给出了试图通过隐匿实现安全的IM pression。的如果我不告诉他们的网址,他们不会知道它的存在。

  • 如果您已经签入等方式来控制页面的渲染权限(因为它似乎你是根据其他地方您的意见做)这个不明确写出来的网址是没有意义的。的更好地甚至没有调用Url.Action方法。

  • 如果您没有按照用户的权限已经控制了页面的渲染,简单地返回空字符串对于网址会留下很多的断裂或破碎看似内容在您的网页。 嘿,这个按钮不会做任何事情,当我preSS吧!

  • 它可以使测试和调试更加复杂:是URL显示不出来,因为权限是不正确的,或者是有另一个bug

  • 的AuthorizedAction方法的行为似乎不一致。返回有时一个URL,和一个空字符串的时候。

控制页面呈现通过动作授权属性:
修改 AuthorizedAction 方法是布尔,然后使用这个结果来控制页面呈现。

Controlling Page Rendering Via Action Authorization attributes: Modify the AuthorizedAction method to be a boolean, then use the result of that to control page rendering.

public static bool AuthorizedAction(this HtmlHelper helper, string controller, string action)
{
    var actions = GetActions(controller, action);
    var authorized = GetMyAuthorizations(actions);
    return user.Roles.Any(userrole => authorized.Roles.Any(role => role == userrole)) ||
       user.Permissions.Any(userPermission => authorized.Permissions.Any(permission => permission == userPermission))
}

然后在你的剃须刀页面中使用此。

Then use this in your razor pages.

@if(Html.AuthorizedAction("User","Add")){
   <div id='add-user-section'>
        If you see this, you have permission to add a user.
        <form id='add-user-form' submit='@Url.Action("User","Add")'>
             etc
        </form>
   </div>
}
else {
  <some other content/>

}

这篇关于如何获得在ASP.NET MVC 4控制器操作自定义注解的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆