ASP.NET MVC5 OWIN拒绝长URL

时间:2014-12-24 14:32:04

标签: iis asp.net-mvc-5 owin url-encoding asp.net-identity-2

我正在创建一个ASP.NET MVC5操作方法,该方法实现密码重置端点并接受包含令牌的电子邮件中的点击。我的实现使用OWIN中间件,非常类似于ASP.NET Identity 2.1 samples application

根据示例应用程序,令牌由UserManager生成并嵌入到通过电子邮件发送给用户的URL中:

var token = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
var encoded = HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(token));
var uri = new Uri(Url.Link("ResetPasswordRoute", new { id = user.Id, token = encoded }));

电子邮件中的链接以MVC端点为目标,该端点接受令牌参数作为其路线段之一:

[Route("reset-password/{id}/{token}"]
public async Task<ActionResult> PasswordResetAsync(int id, string token)
{
    token = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(token));

    // Implementation here
}

但是,对此端点的请求(使用以上述方式生成的URL)会因Bad Request - Invalid URL而失败。

似乎发生此故障是因为URL太长。具体来说,如果我截断令牌段,它会正确连接到MVC端点(当然,令牌参数不再有效)。具体来说,以下截断的URL有效......

http://localhost:53717/account/reset-password/5/QVFBQUFOQ01uZDhCRmRFUmpIb0F3RS9DbCtzQkFBQUFzcko5MEJnYWlrR1RydnVoY2ZwNEpnQUFBQUFDQUFBQUFBQVFaZ0FBQUFFQUFDQUFBQUNVeGZZMzd4OTQ3cE03WWxCakIwRTl4NkVSem1Za2ZUc1JxR2pwYnJSbmJ3QUFBQUFPZ0FBQUFBSUFBQ0FBQUFEcEpnVXFXS0dyM2ZPL2dQcWR1K2x6SkgxN25UVjdMYlE2UCtVRG4rcXBjU0FBQUFE

...但如果添加了一个额外的字符,它将失败...

http://localhost:53717/account/reset-password/5/QVFBQUFOQ01uZDhCRmRFUmpIb0F3RS9DbCtzQkFBQUFzcko5MEJnYWlrR1RydnVoY2ZwNEpnQUFBQUFDQUFBQUFBQVFaZ0FBQUFFQUFDQUFBQUNVeGZZMzd4OTQ3cE03WWxCakIwRTl4NkVSem1Za2ZUc1JxR2pwYnJSbmJ3QUFBQUFPZ0FBQUFBSUFBQ0FBQUFEcEpnVXFXS0dyM2ZPL2dQcWR1K2x6SkgxN25UVjdMYlE2UCtVRG4rcXBjU0FBQUFEf

我认为maxUrlLength的默认IIS配置设置应该与我尝试做的兼容,但我也尝试将其明确设置为更大的值,但这并没有解决问题。

但是,使用Fiddler来检查服务器响应,我可以看到工作URL使用以下标题生成服务器响应...

Server: Microsoft-IIS/8.0

...而较长的网址被拒绝,其回复包含以下标题...

Server: Microsoft-HTTPAPI/2.0

这似乎意味着该URL不会被IIS拒绝,而是被中间件组件拒绝。

所以,我想知道那个组件可能是什么以及我如何解决它的影响。

有什么建议吗?

非常感谢, 添

注意:尽管我在Base64上面的实现在URL中使用它之前对令牌进行了编码,但我还尝试了示例代码中使用的更简单的方法,该方法依赖于UrlHelper.RouteUrl提供的URL编码。这两种技术都存在同样的问题。

1 个答案:

答案 0 :(得分:3)

您不应该在URL的应用程序路径中传递这么长的值,因为它们的长度限制为255个字符。

稍微好一点的替代方法是使用查询字符串参数:

http://localhost:53717/account/reset-password/5?token=QVFBQUFOQ01uZDhCRmRFUmpIb0F3RS9DbCtzQkFBQUFzcko5MEJnYWlrR1RydnVoY2ZwNEpnQUFBQUFDQUFBQUFBQVFaZ0FBQUFFQUFDQUFBQUNVeGZZMzd4OTQ3cE03WWxCakIwRTl4NkVSem1Za2ZUc1JxR2pwYnJSbmJ3QUFBQUFPZ0FBQUFBSUFBQ0FBQUFEcEpnVXFXS0dyM2ZPL2dQcWR1K2x6SkgxN25UVjdMYlE2UCtVRG4rcXBjU0FBQUFEf

根据浏览器和IIS设置,至少2000个字符(完整URL)应该是安全的。

更安全且可扩展的方法是在HTTP标头内传递令牌。