- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的 API 中,我有 2 个端点,第一个端点生成电子邮件以重置密码表单(我使用 UserManager.GeneratePasswordResetTokenAsync
生成 token )。
第二个端点用于实际密码重置(我使用 UserManager.ResetPasswordAsync
)。
我的要求是验证密码重置所需的 token 是否未过期。
在 GitHub 上搜索我找到了 this issue据我发现,这在设计上是不可能的。
然而,通过更深入的搜索,我发现 UserManager.ResetPasswordAsync内部使用来自 Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider 的 ValidateAsync
有了这个,我创建了这个扩展方法:
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using System;
using System.Globalization;
using System.IO;
using System.Text;
namespace Api.Extensions
{
public enum TokenValidity
{
VALID,
INVALID,
INVALID_EXPIRED,
ERROR
}
public static class UserManagerExtensions
{
public static TokenValidity IsResetPasswordTokenValid<TUser, TKey>(this UserManager<TUser, TKey> manager, TUser user, string token) where TKey : IEquatable<TKey> where TUser : class, IUser<TKey>
{
return IsTokenValid(manager, user, "ResetPassword", token);
}
public static TokenValidity IsTokenValid<TUser, TKey>(this UserManager<TUser, TKey> manager, TUser user, string purpose, string token) where TKey : IEquatable<TKey> where TUser : class, IUser<TKey>
{
try
{
//not sure if this is needed??
if (!(manager.UserTokenProvider is DataProtectorTokenProvider<TUser, TKey> tokenProvider)) return TokenValidity.ERROR;
var unprotectedData = tokenProvider.Protector.Unprotect(Convert.FromBase64String(token));
var ms = new MemoryStream(unprotectedData);
using (var reader = ms.CreateReader())
{
var creationTime = reader.ReadDateTimeOffset();
var expirationTime = creationTime + tokenProvider.TokenLifespan;
var userId = reader.ReadString();
if (!String.Equals(userId, Convert.ToString(user.Id, CultureInfo.InvariantCulture)))
{
return TokenValidity.INVALID;
}
var purp = reader.ReadString();
if (!String.Equals(purp, purpose))
{
return TokenValidity.INVALID;
}
var stamp = reader.ReadString();
if (reader.PeekChar() != -1)
{
return TokenValidity.INVALID;
}
var expectedStamp = "";
//if supported get security stamp for user
if (manager.SupportsUserSecurityStamp)
{
expectedStamp = manager.GetSecurityStamp(user.Id);
}
if (!String.Equals(stamp, expectedStamp)) return TokenValidity.INVALID;
if (expirationTime < DateTimeOffset.UtcNow)
{
return TokenValidity.INVALID_EXPIRED;
}
return TokenValidity.VALID;
}
}
catch
{
// Do not leak exception
}
return TokenValidity.INVALID;
}
}
internal static class StreamExtensions
{
internal static readonly Encoding DefaultEncoding = new UTF8Encoding(false, true);
public static BinaryReader CreateReader(this Stream stream)
{
return new BinaryReader(stream, DefaultEncoding, true);
}
public static BinaryWriter CreateWriter(this Stream stream)
{
return new BinaryWriter(stream, DefaultEncoding, true);
}
public static DateTimeOffset ReadDateTimeOffset(this BinaryReader reader)
{
return new DateTimeOffset(reader.ReadInt64(), TimeSpan.Zero);
}
public static void Write(this BinaryWriter writer, DateTimeOffset value)
{
writer.Write(value.UtcTicks);
}
}
}
所以现在我可以添加这张支票了:
if (UserManager.IsResetPasswordTokenValid(user, model.Code) == TokenValidity.INVALID_EXPIRED)
{
return this.BadRequest("errorResetingPassword", "Link expired");
}
我的问题是:
1.有更简单的方法吗?
我的目的是向用户显示电子邮件中的链接已过期的信息,因为现在他只能看到重置密码出现问题。
2.如果没有这样做的内置方法,潜在的安全漏洞是什么?我使用我的扩展方法作为附加检查。如果我的方法返回 true,我仍然使用 ResetPasswordAsync
。
最佳答案
UserManager 具有您可以使用的 VerifyUserTokenAsync 和 VerifyUserToken 方法。
参见 Wouter's answer to the question "How can I check if a password reset token is expired?"了解更多详情。
所以你可以使用类似的东西
if (!UserManager.VerifyUserToken(userId, "ResetPassword", model.code)){
return this.BadRequest("errorResetingPassword", "Link expired");
}
关于c# - ASP.NET Identity 验证 ResetPassword token 是否已过期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51519134/
我一直在尝试了解 ASP.NET Identity 中重置密码和帐户确认的工作原理。我只是想知道 token 是否被存储,如果是,存储在哪里? 使用密码重置功能时收到的链接如下所示 http://lo
是否可以控制通过调用 MembershipUser.ResetPassword() 自动生成的密码的格式? 我希望能够允许或不允许在生成的密码中使用某些特殊字符。 我使用密码格式为 Hashed 的
我正在尝试实现登录系统,因此它使用由 ref.resetPassword() 生成的随 secret 码。 问题是随 secret 码在 24 小时后失效。尝试将 session 长度更改为 24 个
我正在尝试在 ForgetPassword 标记点击时创建手动重置密码。但是当我用用户验证这个 token 时,它总是返回 false。请帮助我这是我的代码 [AllowAnonymous] publ
我使用 Meteor.js,我想自定义重置密码电子邮件正文。我需要在邮件正文中插入 html 代码。我可以使用以下代码来做到这一点: Accounts.emailTemplates.resetPass
我正在尝试实现一个问答密码重置页面,但是这一行: string tempPassword = Membership.Provider.ResetPassword(username, TextB
我想实现: 如果用户尝试使用无效的用户名和密码登录超过 3 次。我想将它们转发到我的“重置密码页面”。 这背后的逻辑是什么?我无法理解这个问题的确切逻辑。请帮忙。 我想申请什么: 从表单文本字段传递默
我使用 Accounts.emailTemplates.resetPassword.text 没有问题,但如果我也使用 Accounts.emailTemplates.resetPassword.ht
在我的 API 中,我有 2 个端点,第一个端点生成电子邮件以重置密码表单(我使用 UserManager.GeneratePasswordResetTokenAsync 生成 token )。 第二
这是我使用 xcode 和 swift 为我的 iOS 应用程序重置密码按钮: //ResetPssword Button @IBAction func ResetPassword(sender: A
我正在使用 asp.net 表单例份验证,我需要能够为用户重置密码。 这是代码: protected void resetPassword(string username) { Members
我在自定义应用程序中遇到此错误: InvalidArgumentException in UrlGenerator.php line 304: Route [password.reset] not d
有人可以告诉我,如何才能在注册的确认后后发送此邮件。无论是忘记密码/重设密码还是注册,此代码都会在每次确认后发送邮件。 var aws = require('aws-sdk'); var ses =
使用 System.Web.Security; 我正在 MVC4 中创建一个 resetPassword 表单: using System.Web.Security; [HttpPost] [Allo
我是一名优秀的程序员,十分优秀!