在ASP.NET MVC中将动作参数与请求Cookie绑定 - 发生了什么?

4
在ASP.NET MVC的几个早期预览版本中,控制器方法的参数会通过检查查询字符串、表单、Cookie和服务器变量集合来解析,详见Stephen Walther的这篇文章
例如,以下代码曾经可以使用:
public class MyController : Controller {

    // This should bind to Request.Cookies["userId"].Value
    public ActionResult Welcome(int userId) {

        WebUser wu = WebUser.Load(userId);
        ViewData["greeting"] = "Welcome, " + wu.Name;
        return(View());
    }
}

但是现在运行到发布候选版本时,它会抛出一个异常,因为它找不到userId的值,即使userId明确出现在请求cookies中。

这个变化在发布说明中有提到吗?如果这是框架的改变,现在是否有推荐的替代方法来绑定 cookies 和服务器变量?

编辑: 感谢那些已经回复的人。我可能选择了一个不好的例子来证明这一点; 我们的代码使用cookies来方便但非必要地保持各种形式的"方便"数据(记住搜索结果的顺序之类的东西),因此它并不纯粹是认证问题。依赖用户 cookies 的安全性问题已经被充分记录; 我更感兴趣的是当前灵活易测试的技术来检索cookie值的建议。 (如您所知,上面的示例可能具有安全风险,但非常容易测试!)


你能发布一下你的路由表设置吗? - Matt Kocaj
在ASP.NET中,如果您执行'Request["blah"]',它会查找查询字符串、表单提交、cookie和我认为是服务器变量(呃)。 如果意图是仅使用查询字符串/表单提交来获取更多“预期”的数据,那么我完全赞成...只是一个猜测而已 :) - Timothy Khouri
请看我的帖子,了解“灵活易测的获取cookie值技巧”。 - Matt Mitchell
3个回答

3

我不认为现在还会检查cookie,我不确定这是有意还是无意的。

最近我写了一个反对RC的应用程序,我使用了这篇文章中的CookieContainer代码和一个自定义的授权属性来处理类似这样的问题:

public class LoginRequiredAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        IAppCookies a = new AppCookies(new CookieContainer());
        return a.UserId != null; /* Better checks here */
    }
}

我的AppCookies.cs仅有一个关于UserId的方法,如下所示(自动解析为int/null):

public int? UserId
{
    get { return _cookieContainer.GetValue<int?>("UserId"); }
    set { _cookieContainer.SetValue("UserId", value, DateTime.Now.AddDays(10)); }
}

然后,请确保您的web.config已设置指向登录页面,格式如下:
<authentication mode="Forms">
<forms loginUrl="~/Login"/>
</authentication>

这意味着在我的控制器中,为了获取用户ID,我需要像这样检索我的cookie:
[LoginRequiredAttribute]
public class RandomController : Controller
{
    BaseDataContext dbContext = new BaseDataContext();
    private readonly IAppCookies _cookies = new AppCookies(new CookieContainer());

    public ActionResult Index()
    {
        return View(new RandomViewData(dbContext, _cookies.UserId));
    }
}

3
我相信正是安全方面的考虑促使他们将其删除:
Stephen Walther的帖子ASP.NET MVC Tip 15中的评论,导致Phil Haack发布了User Input in Sheep's Clothing,特别是他在此处的评论:

@Troy-第一步是阻止开发人员从一开始就采取这种思路。 ;)第一步主要(并行进行)是我们在这种情况下消除这种思路的可能性。

更重要的是,我们可以进行这种改变(经过讨论,我们可能会这样做),但这并不意味着突然可以相信操作方法参数是安全的。

再加上您如何从各种操作构建器类中调用这些方法的复杂性。

我似乎找不到任何明确的文档来说明控制器的行为是否像这样,除了Stephen的帖子,所以我猜它被“悄悄地放弃”了。


0
除了明显的安全隐患,为什么你需要通过路由传递cookie呢?
当然,最好在操作上加上一个授权属性,表示在执行操作之前应该对用户进行身份验证。
归根结底,我认为(希望)微软已经关闭了这个问题,因为它是一个相当大的安全问题。如果是这种情况,你应该考虑重写你的应用程序以符合这个要求。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接