我正在创建一个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编码。这两种技术都存在同样的问题。
答案 0 :(得分:3)
您不应该在URL的应用程序路径中传递这么长的值,因为它们的长度限制为255个字符。
稍微好一点的替代方法是使用查询字符串参数:
http://localhost:53717/account/reset-password/5?token=QVFBQUFOQ01uZDhCRmRFUmpIb0F3RS9DbCtzQkFBQUFzcko5MEJnYWlrR1RydnVoY2ZwNEpnQUFBQUFDQUFBQUFBQVFaZ0FBQUFFQUFDQUFBQUNVeGZZMzd4OTQ3cE03WWxCakIwRTl4NkVSem1Za2ZUc1JxR2pwYnJSbmJ3QUFBQUFPZ0FBQUFBSUFBQ0FBQUFEcEpnVXFXS0dyM2ZPL2dQcWR1K2x6SkgxN25UVjdMYlE2UCtVRG4rcXBjU0FBQUFEf
根据浏览器和IIS设置,至少2000个字符(完整URL)应该是安全的。
更安全且可扩展的方法是在HTTP标头内传递令牌。