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

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

问题描述

我想有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) { ... }

第一对夫妇做一些事情,当用户的不是认证(匿名用户)。第二对夫妇做类似(但不相同)的东西时,用户的认证。

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动作加以区分。我不认为我做了什么错在这里或者忘记做一些事情。我只希望它在n要MVC Asp.net 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 code和我想出了最合适的解决方案我自己。

@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 将处理这个问题。我创建了一个基于用户授权(匿名或授权)选择的动作。这里的code:

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操作。这是为什么?我发现的临ASP.NET MVC框架图书在流程图的答案(的检查出来自己)。异常被抛出,因为有比 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天全站免登陆