使用授权过滤器区分控制器操作 [英] Distinguishing controller actions using authorization filters

查看:186
本文介绍了使用授权过滤器区分控制器操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有4个具有相同名称的动作(控制器方法可能有不同的名称,但他们的 ActionName()属性是相同的所有4个:

I would like to have 4 actions with the same name (controller methods may have a different name, but their ActionName() attribute is the same for all 4 of them:

[ActionName("Same-name")]
public ActionResult AnonAction() { ... }

[HttpPost]
[ActionName("Same-name")]
public ActionResult AnonAction(ModelData data) { ... }

[Authorize]
[ActionName("Same-name")]
public ActionResult AuthAction() { ... }

[HttpPost]
[Authorize]
[ActionName("Same-name")]
public ActionResult AuthAction(OtherData data) { ... }


b $ b

第一对夫妇在用户未进行身份验证(匿名用户)时执行某项操作。当用户 已验证。

The first couple does something when users are not authenticated (anonymous users). The second couple does something similar (but not the same) when users are authenticated.

前三个操作方法按预期工作,但我似乎无法使最后一个工作,它抛出一个异常告诉我,它不能区分POST操作。我不认为我在这里做了什么错,或者忘了做某事。我只是希望它是一个错误在Asp.net MVC 2 RC2。

First three action methods work as expected, but I can't seem to make the last one work. It throws an exception telling me, that it can't distinguish between POST actions. I don't think I've made anything wrong here or forgotten to do something. I just hope it's nto a bug in Asp.net MVC 2 RC2.

有没有人看到我的行动中的任何缺陷?

Does anyone see any flaw in my actions?

推荐答案

@Paco是对的。 AuthorizeAttribute 与操作选择没有任何关系。他的建议不是很正确,感谢他我做了一些挖掘MVC代码,我自己提出了最适当的解决方案。

@Paco is right. AuthorizeAttribute doesn't have anything to do with action selection. His suggestion didn't feel right so thanks to him I did some digging into MVC code and I came up with the most appropriate solution myself.

在MVC中有一些可扩展性。基本上你要做的是写你自己的 ActionMethodSelectionAttribute ,将处理这个。我创建了一个基于用户授权(匿名或授权)选择操作。以下是代码:

There's an extensibility point for these things in MVC. Basically what you have to do is to write you own ActionMethodSelectionAttribute that will handle this. I created one that selects action based on user authorization (either anonymous or authorized). Here's the code:

/// <summary>
/// Attribute restricts controller action execution only to either anonymous or authenticated users
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class AllowAuthenticatedAttribute : ActionMethodSelectorAttribute
{
    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="AllowAuthorizedAttribute"/> allows authenticated or anonymous users to execute decorated controller action.
    /// </summary>
    /// <value><c>true</c> if authenticated users are allowed to execute the action; <c>false</c> if anonymous users are allowed to execute the action.</value>
    public bool Authenticated { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="AllowAuthorizedAttribute"/> class.
    /// </summary>
    /// <param name="authenticated">If set to <c>true</c> only authorized users will be able to access this action.</param>
    public AllowAuthenticatedAttribute(bool authenticated)
    {
        this.Authenticated = authenticated;
    }

    /// <summary>
    /// Determines whether the action method selection is valid for the specified controller context.
    /// </summary>
    /// <param name="controllerContext">The controller context.</param>
    /// <param name="methodInfo">Information about the action method.</param>
    /// <returns>
    /// true if the action method selection is valid for the specified controller context; otherwise, false.
    /// </returns>
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    {
        if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }
        return this.Authenticated == controllerContext.HttpContext.User.Identity.IsAuthenticated;
    }
}



其他观察



当我用我的自定义属性装饰我的动作方法时,我仍然有同样的异常,直到我添加 [HttpGet] 到我的GET动作。这是为什么?我在 Pro ASP.NET MVC Framework 图书(自己检查一下)。抛出异常,因为 ActionMethodSelectorAttribute 不仅仅有一个操作方法。通常我们只是装饰出POST动作,但在这种情况下,所有的装饰。 2表示匿名用户,2表示经过身份验证的用户。这就是为什么您在添加更多广告素材时必须同时使用 HttpGet HttpPost 选择器属性。

Additional observation

When I decorated my action methods with my custom attribute I still got the same exception until I added [HttpGet] to my GET actions. Why is that? I found the answer in the flowchart in Pro ASP.NET MVC Framework book (check it out yourself). Exception was thrown because there were more than just one action method with ActionMethodSelectorAttribute. Normally we just decorate out POST actions, but in this case all of them were decorated. 2 for anonymous and 2 for authenticated users. That's why you have to use both HttpGet and HttpPost on action methods when you add more selector attributes to them.

我的控制器操作现在看起来像这样

My controller actions now look like this

[HttpGet]
[AllowAuthenticated(false)]
[ActionName("Same-name")]
public ActionResult AnonAction() { ... }

[HttpPost]
[AllowAuthenticated(false)]
[ActionName("Same-name")]
public ActionResult AnonAction(ModelData data) { ... }

[HttpGet]
[Authorize]
[AllowAuthenticated(true)]
[ActionName("Same-name")]
public ActionResult AuthAction() { ... }

[HttpPost]
[Authorize]
[AllowAuthenticated(true)]
[ActionName("Same-name")]
public ActionResult AuthAction(OtherData data) { ... }

这篇关于使用授权过滤器区分控制器操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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