NancyFx RequiresAuthentication扩展返回303而不是403

时间:2014-03-06 00:02:53

标签: nancy

我不确定我做错了什么或者有某种错误。如果它是一个bug,那么我认为这会立即出现。无论哪种方式:

我从这里使用扩展方法RequiresAuthentication:

https://github.com/NancyFx/Nancy/blob/9d3c650575cba109e620ab163f4fda26a0536036/src/Nancy/Security/ModuleSecurity.cs

使用SecurityHooks

https://github.com/NancyFx/Nancy/blob/9d3c650575cba109e620ab163f4fda26a0536036/src/Nancy/Security/SecurityHooks.cs

或具体代码:

public static void RequiresAuthentication(this INancyModule module)
{
    module.AddBeforeHookOrExecute(SecurityHooks.RequiresAuthentication(), "Requires Authentication");
}

SecurityHooks:

public static Func<NancyContext, Response> RequiresAuthentication()
{
    return UnauthorizedIfNot(ctx => ctx.CurrentUser.IsAuthenticated());
}

private static Func<NancyContext, Response> UnauthorizedIfNot(Func<NancyContext, bool> test)
{
    return HttpStatusCodeIfNot(HttpStatusCode.Unauthorized, test);
}

private static Func<NancyContext, Response> HttpStatusCodeIfNot(HttpStatusCode statusCode, Func<NancyContext, bool> test)
 {
        return (ctx) =>
        {
            Response response = null;
            if (!test(ctx))
            {
                response = new Response { StatusCode = statusCode };
            }

            return response;
        };
    }

如果用户未经过身份验证,您可以看到HttpStatusCode.Unauthorized 应该。看起来很简单。当我对以下路线进行AJAX调用时:

Post["/comment/flag/{Id}"] = s =>
{
            this.RequiresAuthentication();
            return new IdResponse { Id = commentRepo.FlagComment(Context.CurrentUser.UserName, s.Id) };
};

我要回到303,然后用200重定向到登录URL。哎呀。根本没有预料到。

为了确保我不是完全疯了,我做了以下工作并且工作正常:

Post["/comment/{Id}"] = s =>
        {
            if ((Context.CurrentUser == null) ||
                    String.IsNullOrWhiteSpace(Context.CurrentUser.UserName))
            {
                return HttpStatusCode.Forbidden;
            }

            var req = this.Bind<CommentRequest>();
            return commentRepo.AddComment(Context.CurrentUser.UserName, s.Id, req.Comment);
        };

这会返回预期的403.但是谁想把它粘贴到所有地方......不是我。我正在试图弄清楚如何编写自己在路线运行之前执行的东西,但我是Nancy的新手。

奇怪的是,如果我改变了:

return HttpStatusCode.Forbidden; 

进入

return new Response { StatusCode = HttpStatusCode.Forbidden };

然后我再次收到303和200的回复。似乎有些东西坏了。谁能给我一些见解或答案我做错了什么?南希似乎对我不利,特别是响应等级......

2 个答案:

答案 0 :(得分:3)

我遇到了和你一样的问题 - 什么都没有打破。

FormsAuthentication.Enable(pipelines, formsAuthConfiguration);

此代码将函数添加到管道之前和之后。它需要每401,并将其更改为303,因为您已定义用户应该在未登录时被重定向。

为了防止这种情况发生,您可以将DisableRedirect属性设置为true。您实际上可以在所有Ajax请求上自动执行此操作:

new FormsAuthenticationConfiguration()
{
    ...,
    DisableRedirect = context.Request.IsAjaxRequest()
};

另外,请确保您的请求将X-Requested-With标头设置为XMLHttpRequest,否则nanacy无法检测到它是ajax请求。您当然可以随意检测正确的请求(基于URL,...),以便将DisableRedirect设置为true。

答案 1 :(得分:2)

目前它返回HttpStatusCode.Unauthorized或401似乎是正确的。我尝试将ContentType设置为application / json,但没有帮助。

当我改变它返回403时它会发回403.虽然我认为技术上这不是正确的反应,但它比我以前得到的神秘303更好。