ASP.NET-Identität: Benutzerdefinierte RefreshTokens vs. integriertes AspNetUserToken

Post a reply

Smilies
:) :( :oops: :chelo: :roll: :wink: :muza: :sorry: :angel: :read: *x) :clever:
View more smilies

BBCode is ON
[img] is ON
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: ASP.NET-Identität: Benutzerdefinierte RefreshTokens vs. integriertes AspNetUserToken

by Guest » 03 Jan 2025, 13:09

Ich implementieren derzeit eine tokenbasierte Authentifizierung mit Aktualisierungstokens in meiner .NET-App. Im Moment habe ich eine benutzerdefinierte RefreshTokens-Sammlung in meinem ApplicationUser:

Code: Select all

public class ApplicationUser : IdentityUser
{
public virtual ICollection RefreshTokens { get; set; } = new List();
}
Mir ist aufgefallen, dass ASP.NET Identity standardmäßig eine AspNetUserTokens-Tabelle generiert. Erfinde ich hier das Rad neu? Könnte ich einfach die Token-Methoden von UserManager (SetAuthenticationTokenAsync/GetAuthenticationTokenAsync) verwenden, anstatt meinen eigenen Token-Dienst zu verwalten? Muss ich meinen eigenen TokenProvider implementieren?

Code: Select all

 public async Task LoginAsync(LoginPayload request)
{
var user = await userManager.FindByEmailAsync(request.Username);
if (user == null || !await userManager.CheckPasswordAsync(user, request.Password))
throw new Exception("Invalid email or password");

if(!user.EmailConfirmed)
throw new Exception("Email not confirmed");

var accessToken = tokenService.GenerateAccessToken(user);
var refreshToken = tokenService.GenerateRefreshToken();

user.RefreshTokens.Add(refreshToken);
await context.SaveChangesAsync();

return new LoginResponse(
accessToken,
refreshToken.Token,
(int)(refreshToken.ExpiresAt - DateTimeOffset.UtcNow).TotalMilliseconds,
user.UserName!
);
}

public async Task RefreshTokenAsync(string accessToken, string refreshToken)
{
var principal = tokenService.GetPrincipalFromExpiredToken(accessToken);
if (principal == null)
throw new Exception("Invalid access token");

var user = await userManager.FindByNameAsync(principal.Identity!.Name!);
if (user == null)
throw new Exception("User not found");

var existingToken = await context.RefreshToken
.FirstOrDefaultAsync(rt => rt.Token == refreshToken);
if (existingToken == null || existingToken.ExpiresAt < DateTime.UtcNow)
throw new Exception("Invalid or expired refresh token");

var newAccessToken = tokenService.GenerateAccessToken(user);
var newRefreshToken = tokenService.GenerateRefreshToken();

context.RefreshToken.Remove(existingToken);
user.RefreshTokens.Add(newRefreshToken);
await context.SaveChangesAsync();

return new LoginResponse(
newAccessToken,
newRefreshToken.Token,
(int)(newRefreshToken.ExpiresAt - DateTimeOffset.UtcNow).TotalMilliseconds,
user.UserName!
);
}

Top