-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added refresh endpoint for access token #120
Conversation
@@ -14,5 +14,6 @@ public static void MapEndpoints(WebApplication app) | |||
app.MapPost("/authentication/login", Login.PostLogin).WithTags("Authentication").WithOpenApi(); | |||
app.MapPut("/authentication/changePassword", ChangePassword.PutChangePassword).WithTags("Authentication").WithOpenApi().RequireAuthorization("user"); | |||
app.MapPut("/authentication/logout", Logout.PutLogout).WithTags("Authentication").WithOpenApi().RequireAuthorization("user"); | |||
app.MapPut("/authentication/refreshAccess", RefreshEndpointAccessToken.PostRefreshAccessToken).WithTags("Authentication").WithOpenApi().RequireAuthorization("user"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change the endpoint path to "authentication/refreshAccessToken" please
{ | ||
|
||
/// <summary> | ||
/// Creates a new access token. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... based on a refresh token
return TypedResults.Unauthorized(); | ||
} | ||
|
||
User? user = databaseHandle.Users.Where(u => u.Username == requestBody.UserName).FirstOrDefault(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You dont need to use a body here, just use the claims from the token to get the username
|
||
User? user = databaseHandle.Users.Where(u => u.Username == requestBody.UserName).FirstOrDefault(); | ||
|
||
// If no user is found matching the redentials, return 404. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be no possibility for that, since the user is authenticated using a refresh token. Still, should the user be null, just return unauthorized. This is not a login request.
{ | ||
databaseHandle.Database.EnsureCreated(); | ||
|
||
if (!AnonKeyBackend.Authentication.TokenActions.ValidateClaimsOnRequest(userClaimsPrincipal, databaseHandle)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set isRefreshRequest = true
here
} | ||
|
||
// Generate a new token and return it to the user. | ||
Token refreshToken = tokenService.GenerateNewToken(user, "RefreshToken"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--
|
||
// Generate a new token and return it to the user. | ||
Token refreshToken = tokenService.GenerateNewToken(user, "RefreshToken"); | ||
Token accessToken = tokenService.GenerateNewToken(user, "AccessToken"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass parent token uuid to this call
Ok<ApiDatastructures.Authentication.Login.AuthenticationLoginResponseBody>, | ||
NotFound<ApiDatastructures.RequestError.ErrorResponseBody>, | ||
UnauthorizedHttpResult> | ||
PostRefreshAccessToken(ClaimsPrincipal userClaimsPrincipal, ApiDatastructures.Authentication.Login.AuthenticationLoginRequestBody requestBody, AnonKeyBackend.Authentication.TokenService tokenService, Data.DatabaseHandle databaseHandle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please define your own return schemas in ApiDatastructures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, see comments for things that still need fixing.
@@ -0,0 +1,20 @@ | |||
namespace AnonKeyBackend.ApiDatastructures.Authentication.RefreshTokens; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally name the Namespace more something like "RefreshAccessToken" (make sure to rename the folder appropriately)
/// <summary> | ||
/// Represents a token object in the response to a Refresh request. | ||
/// </summary> | ||
public class AuthenticationRefreshTokens |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename the class to something like "AuthenticationRefreshAccessToken" to avoid name conflicts
/// <summary> | ||
/// The body of the response to a Refresh request. | ||
/// </summary> | ||
public class AuthenticationRefreshTokensResponseBody |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename the class to something like "AuthenticationRefreshAccessTokenResponseBody" to avoid name conflicts
/// <summary> | ||
/// The token for refreshing the access token or the refresh token itself | ||
/// </summary> | ||
public AuthenticationRefreshTokens? RefreshToken { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There wont be a RefreshToken returned by this request, so this property can be removed.
return TypedResults.Unauthorized(); | ||
} | ||
|
||
User? userName = databaseHandle.Users.Where(u => u.Username == user.Identity.Name).FirstOrDefault(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This variable name may be misleading, as it implies type "string", while being "User?".
- You are missing a null check on user.Identity (formal requirement mostly...)
return TypedResults.Unauthorized(); | ||
} | ||
|
||
string tokenUuid = user.Claims.First(c => c.Type == "TokenParent").Value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The token used for authentication against this endpoint is a RefreshToken, use the TokenUuid claim instead of TokenParent. (TokenParent is not populated for refresh tokens)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🚀
No description provided.