MVC 5.0 [AllowAnonymous] 和新的 IAuthenticationFilter [英] MVC 5.0 [AllowAnonymous] and the new IAuthenticationFilter

查看:20
本文介绍了MVC 5.0 [AllowAnonymous] 和新的 IAuthenticationFilter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我创建一个新的 asp.net mvc 4.0 应用程序时,我做的第一件事就是创建和设置自定义授权全局过滤器,如下所示:

When I create a new asp.net mvc 4.0 application, one of the first thing I do, is create and set a custom authorize global filter like so:

//FilterConfig.cs
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
 //filters.Add(new HandleErrorAttribute());
 filters.Add(new CustomAuthorizationAttribute());
}

然后我像这样创建CustomAuthorizationAttribute:

//CustomAuthorizationAttribute.cs
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())  
        {
            //Handle AJAX requests
            filterContext.HttpContext.Response.StatusCode = 403;
            filterContext.Result = new JsonResult { JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }
        else
        {
            //Handle regular requests
            base.HandleUnauthorizedRequest(filterContext); //let FormsAuthentication make the redirect based on the loginUrl defined in the web.config (if any)
        }
    }

我有两个控制器:HomeControllerSecureController

I have two controllers: HomeController and SecureController

HomeController 用 [AllowAnonymous] 属性修饰.

The HomeController is decorated with the [AllowAnonymous] attribute.

SecureController NOT[AllowAnonymous] 属性修饰.

The SecureController is NOT decorated with the [AllowAnonymous] attribute.

HomeControllerIndex() ActionResult 显示一个带有简单按钮的视图.

The Index() ActionResult of the HomeController displays a View with a simple button.

当我单击按钮时,我对位于 SecureController 中的 GetData() 方法进行了 ajax 调用,如下所示:

When I click the button, I make an ajax call to a GetData() method that lives inside the SecureController like so:

$("#btnButton").click(function () {
    $.ajax({
        url: '@Url.Action("GetData", "Secure")',
        type: 'get',
        data: {param: "test"},
        success: function (data, textStatus, xhr) {
            console.log("SUCCESS GET");
        }
    });
});

不用说,当我点击按钮时,我触发了 CustomAuthorizationAttribute 因为它是一个全局过滤器,但也因为 SecureController 没有用 修饰[AllowAnonymous] 属性.

Needless to say, when I click the button, I trigger the CustomAuthorizationAttribute because it is a global filter but also because the SecureController is NOT decorated with the [AllowAnonymous] attribute.

好的,我的介绍完毕...

Ok, I’m done with my introduction...

随着 asp.net mvc 5.0 的引入,我们现在引入了一个新的身份验证过滤器,它恰好在之前触发授权过滤器(这很棒,让我们可以更精细地控制如何区分未经身份验证的用户 (http 401) 与经过身份验证的用户以及碰巧未获得授权的用户 (http 403)).

With the introduction of asp.net mvc 5.0, we are now introduced to a new authentication filter which happens to get triggered before the authorization filter (which is great and gives us more granular control on how I can differentiate a user that is NOT authenticated (http 401) from a user that IS authenticated and who happens to NOT be authorized (http 403)).

为了尝试这个新的身份验证过滤器,我创建了一个新的 asp.net mvc 5.0(VS Express 2013 for Web)并开始执行以下操作:

In order to give this new authentication filter a try, I’ve created a new asp.net mvc 5.0 (VS Express 2013 for Web) and started by doing the following:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    //filters.Add(new HandleErrorAttribute());
    filters.Add(new CustomAuthenticationAttribute());   //Notice I'm using the word Authentication and not Authorization
}

那么属性:

public class CustomAuthenticationAttribute : ActionFilterAttribute, IAuthenticationFilter 
{
    public void OnAuthentication(AuthenticationContext filterContext)
    {

    }

    public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
    {
        var user = filterContext.HttpContext.User;
        if (user == null || !user.Identity.IsAuthenticated)
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }
    }
}

我创建了一个 HomeController.HomeController[AllowAnonymous] 属性修饰.

I’ve created a HomeController. The HomeController is decorated with the [AllowAnonymous] attribute.

在从 VS 2013 启动应用程序之前,我在 CustomAuthenticationAttribute 的两个方法(OnAuthenticationOnAuthenticationChallenge)中设置了两个断点.

Before launching the application from VS 2013, I’ve set two break points inside both methods of my CustomAuthenticationAttribute (OnAuthentication and OnAuthenticationChallenge).

当我启动应用程序时,我遇到了第一个断点 (OnAuthentication).然后,令我惊讶的是,我的 HomeController Index() ActionResult 中的代码被执行,并且只有在我返回 View() 之后才会执行我在 OnAuthenticationChallenge() 方法上遇到了断点.

When I launch the application, I hit the first break point(OnAuthentication). Then, to my surprise, the code within the Index() ActionResult of my HomeController gets executed and only after I return the View() do I hit the break point on the OnAuthenticationChallenge() method.

问题:我有两个问题.

问题 1)
我的印象是 [AllowAnonymous] 属性会自动绕过我的 CustomAuthenticationAttribute 中的任何代码,但我错了!我是否需要手动检查[AllowAnonymous] 属性是否存在并跳过任何代码?

Question 1)
I was under the impression that the [AllowAnonymous] attribute would automagically bypass any code within my CustomAuthenticationAttribute but I was wrong! Do I need to manually check for the existence of the [AllowAnonymous] attribute and skip any code?

问题 2)为什么我的 HomeControllerIndex() 方法中的代码在 OnAuthentication 之后执行?才意识到在我返回 View() 之后,OnAuthenticationChallenge() 中的代码会被执行吗?

Question 2) Why is the code inside my Index() method of my HomeController gets executed after the OnAuthentication? Only to realize that after I return View() do the code inside the OnAuthenticationChallenge() gets executed?

我担心的是,如果用户未通过身份验证,我不希望 Index() 方法中的代码被执行.

My concern is that I do not want the code from the Index() method to get executed if the user is NOT authenticated.

也许我看错了.

如果有人能帮我解释一下,那就太好了!

If anyone can help me shed some light on this, that’d be great!

真诚的文斯

推荐答案

关于:问题 1)我的印象是 [AllowAnonymous] 属性会自动绕过我的 CustomAuthenticationAttribute 中的任何代码,但我错了!我是否需要手动检查 [AllowAnonymous] 属性是否存在并跳过任何代码?

据我所知,[AllowAnonymous] 属性与 CustomAuthenticationAttribute 无关.他们有不同的目的.[AllowAnonymous] 会在授权上下文中起作用,但不会在身份验证上下文中起作用.

As far as I know [AllowAnonymous] attribute has nothing to do with a CustomAuthenticationAttribute. They have different purposes. [AllowAnonymous] would have an effect during an Authorization context, but not in Authentication context.

已实施身份验证过滤器以设置身份验证上下文.例如,AuthenticationContext 为您提供执行身份验证的信息.您可以使用此信息根据当前上下文做出身份验证决策.例如,您可以根据身份验证上下文决定将 ActionResult 修改为不同的结果类型,或者您可以根据身份验证上下文等决定更改当前主体.

The Authentication filter has been implemented for setting up authentication context. For instance, AuthenticationContext provides you information for performing authentication. You can use this information to make authentication decisions based on the current context. For example, you may decide to modify the ActionResult to different result type based on the authentication context, or you may decide to change the current principal based on the authentication context etc.

OnAuthenticationChallenge 方法在 OnAuthentication 方法之后运行.您可以使用 OnAuthenticationChallenge 方法对请求执行其他任务.

OnAuthenticationChallenge method runs after the OnAuthentication method. You can use OnAuthenticationChallenge method to perform additional tasks on the request.

关于:问题 2) 为什么我的 HomeController 的 Index() 方法中的代码在 OnAuthentication 之后被执行?才意识到在我返回 View() 之后,OnAuthenticationChallenge() 中的代码会被执行吗?

这是预期的行为.由于您有一个全局注册的身份验证过滤器,因此首先要做的是,在执行任何操作之前,它会首先触发 OnAuthentication 事件,正如您所注意到的.然后是执行索引后的 OnAuthenticationChallenge.一旦操作成功,任何与该操作相关的身份验证过滤器(即索引)将运行 OnAuthenticationChallenge,以便它可以对操作结果做出贡献.正如您在 OnAuthenticationChallenge 代码中所做的那样,您可以将 ActionResult 修改为 HttpUnauthorizedResult,这将与 ActionResult 协商.

This is the expected behaviour. Since the you have a Globally registered Authentication filter, the very first thing is that, before any action executes, it would first fire the OnAuthentication event as you would have noticed. Then the OnAuthenticationChallenge after the Index being executed. Once the Action is succeeded any authentication filter relevant that Action (i.e Index), would run the OnAuthenticationChallenge so it can contribute to the action result. As you have in your code for OnAuthenticationChallenge you can modify the ActionResult to an HttpUnauthorizedResult this would get negotiated with the ActionResult.

这篇关于MVC 5.0 [AllowAnonymous] 和新的 IAuthenticationFilter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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