Wenn Sie sich den von ASP.Net Identity erstellten Benutzer ansehen, sehen Sie eine Spalte SecurityStamp
, die im Grunde Hash ist und in allen passwortbezogenen Szenarien verwendet wird. In der Tat wird es geändert, wenn ein Benutzer sein Passwort ändert.
Wenn Sie auf das Zurücksetzen des Passworts klicken, wird SecurityStamp
mit diesem Benutzer verknüpft, um das Token zu generieren, das in E-Mail gesendet wird. Sehen Sie den Quellcode in GenerateAsync
Methode hier (es gibt 2 Anbieter)
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);
}
oder
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);
}
Sobald ein Benutzer auf den Link klickt und neues Passwort einreicht Token, die in einer E-Mail gesendet werden, werden ebenfalls gesendet und gegen den SecurityStamp validiert.
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);
}
Oder
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;
}
Sobald es erfolgreich das Token-Identity-System weiter aktualisiert die Benutzerdaten mit neuen SecurityStamp
.Mit all dieser Antwort auf Ihre Fragen
Ans 1 - Token ist nicht gespeichert und Link in E-Mail ist sofort aktiv. Ich habe ein vollständig getestetes Produktionssystem und weder ich noch die Benutzer müssen warten, bis der Link aktiv ist.
Ans 2- Ich denke, der Standardwert ist 1 Tag. Sie können es ändern, indem Sie
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>
(dataProtectionProvider.Create("ASP.NET Identity"))
{
TokenLifespan = TimeSpan.FromHours(1) //Any custom TimeSpan
};
}
Am 3 in Create
Methode der ApplicationUserManager
Klasse unter Code hinzufügen - Nur 1 wird das heißt arbeiten je nachdem, was Benutzer zum ersten Mal ändert, weil nach, dass die Sicherheit Stempel klickt und es wird das Token in anderen 2 E-Mail ungültig machen.
Hoffe, das hilft.
Können Sie meine Antwort überprüfen? Habe ich etwas verpasst ? –