【问题标题】:How to prevent user from accessing certain URL directly in ASP.Net MVC 5如何防止用户在 ASP.Net MVC 5 中直接访问某些 URL
【发布时间】:2017-04-24 04:06:52
【问题描述】:

好的,所以我正在通过做一些小项目来学习 ASP.Net MVC 5。我正在实施忘记密码功能。这是流程:

  1. 用户点击忘记密码链接。
  2. 重定向到用户输入电子邮件的页面。
  3. 接收令牌并重定向到页面以输入接收到的令牌
  4. 被重定向到“密码”和“确认密码”页面

现在所有这些页面都有其单独的 URL,并且页面应该按该顺序打开。但是如果我在我的浏览器链接中输入可能是第 3 步(输入令牌)或第 4 步的 URL(输入新密码)的 URL,我可以打开相应的页面。但我不希望那样。如果有人没有按照步骤 1 到 4 进行操作,则他们无法直接打开任何乱序 URL。如何实现以上功能。

注意:如果我们在控制器操作中添加[Authorize] 属性,那么无论我们在浏览器中访问哪个 URL,我们总是会被重定向到登录页面(前提是尚未登录)。我可以实现上述目标吗?所以,如果有人试图直接打开/VerifyToken页面,那么他应该被重定向到页面/SendEmailForReceiveingToken

编辑 1

好的,事情就是这样。为了识别正确的人,我使用了令牌。但是为了检查我的数据库中的令牌字段,我想唯一地了解用户。为此,我正在使用电子邮件 ID。所以基本上我用电子邮件 ID 查询数据库以找到用户,然后检查该行中设置的令牌。但是如果有人直接去验证令牌,那么我将无法知道他的电子邮件ID。截至目前,我将电子邮件作为 token pageresetpassword page 之间的隐藏字段传递

编辑 2 所以在上午 12:00 用户得到了令牌。但他没有继续“重置密码”。 2分钟后他来了,直接进入/VerifyToken页面,输入token。所以现在我无法访问电子邮件 ID。我现在如何验证令牌。我不想查询整个令牌列并匹配相应的行。

【问题讨论】:

  • 例如,任意用户直接打开第 3 页有什么问题?如果他没有通过电子邮件收到的有效令牌来输入,那么它将毫无用处。一旦您在下一步进行适当的验证以验证令牌,他将无法做任何事情。
  • 如果他们去那个页面怎么办:如果他们没有令牌,他们就不会看到他们不应该看到的东西。
  • 很公平。可能是我想太多了。感谢您的回复。 :)
  • @CodingYoshi:你能看到我的编辑吗
  • @Unbreakable 关于您的Edit 1,如果您没有电子邮件并且用户使用 URL 查看页面,则将用户返回到错误页面。很简单。

标签: c# asp.net asp.net-mvc asp.net-mvc-5


【解决方案1】:

任意用户打开例如第 3 页应该输入有效令牌并没有错。如果他之前没有收到过这样的有效令牌,并且您在下一步对令牌进行了适当的验证,那么这个用户就无法做任何有用的事情。您使设计过于复杂。

只需在实际密码重置发生的步骤上进行适当的验证 - 验证是否输入了有效的令牌。只要令牌有效,提交此令牌的页面就无关紧要了。

【讨论】:

  • 所以,答案的最后一行。您答案的最后一行将如何为我工作。请指导我
  • 我在这里遗漏了什么吗?我只是一个初学者。请指导我。
  • 好的,这就是它的工作原理。用户请求重置密码。您生成一个令牌并将其与请求密码重置的用户电子邮件相关联。您将这对 token+email 存储在数据库中。在 url 中生成包含令牌的链接并将其发送到用户的电子邮件:http://example.com/reset?token=xxxx。当请求此链接时,您在数据库中搜索是否有值为 xxxx 的令牌,然后显示用户的密码重置表单。密码重置表单将包含令牌、用户电子邮件(作为隐藏字段)和新密码。
  • 提交表单后,您再次验证令牌是否与数据库中的电子邮件(来自隐藏字段)匹配,如果匹配,则重置密码。
  • 在我的情况下,我将令牌发送到他们的电子邮件 ID。只是说。
【解决方案2】:

您认为需要电子邮件地址来验证令牌是正确的。但是,您不需要为此目的建立严格的流程。

您可以将电子邮件地址插入密码重置网址作为查询参数。示例网址:

http://www.example.com/resetpassword/ZXhhbXBsZQ?email=example@example.com

然后您使用指定的电子邮件查询用户的令牌。

或者您可以在第 3 步或第 4 步询问用户电子邮件。如果您查看 Visual Studio 创建的基于 ASP.NET Identity 的默认项目,您就会看到。密码表单还要求用户输入他的电子邮件。

或者,您可以使用更高级的令牌,其中可以嵌入信息。例如,可以将用户主体嵌入到 JWT 令牌中。但是,我个人认为这是密码重置的过度杀伤力。一个明显的缺点是 JWT 令牌,因此您的密码重置 URL 会更长。

【讨论】:

    【解决方案3】:

    假设您的令牌实际上是唯一的,您实际上不需要知道用户的电子邮件地址/用户名。该令牌充当用户记录的(临时)唯一 ID,因此您可以将该令牌保留在“输入您的新密码”视图中,并在您的重置逻辑中使用它:

    public bool UpdatePasswordForToken(string token, string newPassword)
    {
        bool success = false;
    
        var user = Context.Users.SingleOrDefault(u => u.ResetToken.Equals(token, StringComparison.OrdinalIgnoreCase));
        if (user != null)
        {
            var password = Crypto.HashPassword(newPassword);
            if (!string.IsNullOrWhiteSpace(password))
            {
                user.Password = password;
                user.ResetToken = null;
    
                Context.SaveChanges();
    
                success = true;
            }
        }
    
        return success;
    }
    

    这假设您不只是在用户完成密码重置时登录。我重定向到登录页面(带有成功消息)。即使有人设法猜到了一个有效的重置令牌(这意味着这些令牌并不是真正唯一的),他们也需要知道他们刚刚重置了哪个用户名,以便以(现在被泄露的)用户身份登录。

    如果您真的只让用户遵循您的工作流程,那么显而易见的答案似乎是检查 Request.UrlReferrer 值,如果当前操作不是您想要执行此操作的操作,则将用户从当前操作中退回。不过,UrlReferrer 并不是万无一失的,所以我建议您像上面提到的那样简化您的工作流程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多