gpt4 book ai didi

asp.net-identity - AspnetIdentity 在哪里存储 UserToken?

转载 作者:行者123 更新时间:2023-12-04 23:48:14 26 4
gpt4 key购买 nike

我有 ASP.Net MVC5 应用程序。在选择个人身份验证时创建应用程序时,visual studio 使用脚手架并添加用于登录、创建用户、忘记密码等的代码。我正在使用 ForgotPassword 功能的这个默认实现。这就是忘记密码的工作原理。

1> 用户点击忘记密码链接。

2> 用户输入他的电子邮件地址。

3> 应用程序创建新的 token 并发送带有查询字符串中带有 token 的返回 URL 的电子邮件。

4> 用户点击电子邮件中的链接并被重定向到 ResetPassword 页面。

5> 用户输入新密码并点击提交。

6> 应用程序验证用户和 token 并重置密码。

题。

1> 用户在收到电子邮件后可能不会立即点击链接,他可能会在一段时间甚至几天后点击。 ASP.NET 应用程序在哪里存储 token ?我在数据库中没有看到它。

2> token 是否有任何过期时间。

3> 在忘记密码屏幕上,用户输入他的电子邮件并单击提交以接收带有 token 的电子邮件。假设他这样做了 3 次。因此,他收到 3 封电子邮件,其中包含 3 个不同的 token 。然后他点击任何一封电子邮件中的链接并重置密码。其他 2 封电子邮件中未使用的 token 会怎样,它们仍然有效吗?用户可以单击其他电子邮件中的链接并重置密码吗?

最佳答案

基本上,如果您查看由 ASP.Net Identity 创建的用户,您会看到一列 SecurityStamp它基本上是散列,用于所有与密码相关的场景。事实上,当用户更改他的密码时,它就会改变。

当您点击重置密码时 SecurityStamp与该用户关联的用于生成通过电子邮件发送的 token 。源码见GenerateAsync方法在这里(有 2 个提供者)

https://github.com/aspnet/Identity/blob/dev/src/Microsoft.AspNetCore.Identity/TotpSecurityStampBasedTokenProvider.cs

public virtual async Task<string> GenerateAsync(string purpose, UserManager<TUser> manager, TUser user)
{
if (manager == null)
{
throw new ArgumentNullException(nameof(manager));
}
var token = await manager.CreateSecurityTokenAsync(user);
var modifier = await GetUserModifierAsync(purpose, manager, user);
return Rfc6238AuthenticationService.GenerateCode(token, modifier).ToString("D6", CultureInfo.InvariantCulture);
}

或者

https://github.com/aspnet/Identity/blob/dev/src/Microsoft.AspNetCore.Identity/DataProtectionTokenProvider.cs
    public virtual async Task<string> GenerateAsync(string purpose, UserManager<TUser> manager, TUser user)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var ms = new MemoryStream();
var userId = await manager.GetUserIdAsync(user);
using (var writer = ms.CreateWriter())
{
writer.Write(DateTimeOffset.UtcNow);
writer.Write(userId);
writer.Write(purpose ?? "");
string stamp = null;
if (manager.SupportsUserSecurityStamp)
{
stamp = await manager.GetSecurityStampAsync(user);
}
writer.Write(stamp ?? "");
}
var protectedBytes = Protector.Protect(ms.ToArray());
return Convert.ToBase64String(protectedBytes);
}

一旦用户单击链接并提交通过电子邮件发送的新密码 token ,也会提交并根据 SecurityStamp 进行验证。
    public virtual async Task<bool> ValidateAsync(string purpose, string token, UserManager<TUser> manager, TUser user)
{
if (manager == null)
{
throw new ArgumentNullException(nameof(manager));
}
int code;
if (!int.TryParse(token, out code))
{
return false;
}
var securityToken = await manager.CreateSecurityTokenAsync(user);
var modifier = await GetUserModifierAsync(purpose, manager, user);
return securityToken != null && Rfc6238AuthenticationService.ValidateCode(securityToken, code, modifier);
}

或者
    public virtual async Task<bool> ValidateAsync(string purpose, string token, UserManager<TUser> manager, TUser user)
{
try
{
var unprotectedData = Protector.Unprotect(Convert.FromBase64String(token));
var ms = new MemoryStream(unprotectedData);
using (var reader = ms.CreateReader())
{
var creationTime = reader.ReadDateTimeOffset();
var expirationTime = creationTime + Options.TokenLifespan;
if (expirationTime < DateTimeOffset.UtcNow)
{
return false;
}

var userId = reader.ReadString();
var actualUserId = await manager.GetUserIdAsync(user);
if (userId != actualUserId)
{
return false;
}
var purp = reader.ReadString();
if (!string.Equals(purp, purpose))
{
return false;
}
var stamp = reader.ReadString();
if (reader.PeekChar() != -1)
{
return false;
}

if (manager.SupportsUserSecurityStamp)
{
return stamp == await manager.GetSecurityStampAsync(user);
}
return stamp == "";
}
}
// ReSharper disable once EmptyGeneralCatchClause
catch
{
// Do not leak exception
}
return false;
}

一旦成功验证 token 身份系统,将使用新的 SecurityStamp 进一步更新用户详细信息。 .说了这么多,回答你的问题

Ans 1 - token 未存储,电子邮件中的链接立即处于事件状态。我有一个经过全面测试的生产系统,我和用户都不必等待链接处于事件状态。

Ans 2-我认为默认值为 1 天。您可以通过在 Create 中添加以下代码来更改它 ApplicationUserManager的方法类(class)
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>
(dataProtectionProvider.Create("ASP.NET Identity"))
{
TokenLifespan = TimeSpan.FromHours(1) //Any custom TimeSpan
};
}

Ans 3 - 只有 1 个有效,即无论哪个用户先点击,因为在该安全戳更改之后,它会使其他 2 封电子邮件中的 token 无效。

希望这可以帮助。

关于asp.net-identity - AspnetIdentity 在哪里存储 UserToken?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38670584/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com