I've been investigating the new .NET 8 Web APIs and identity to see how they work as I'm looking to upgrade from an existing .NET 4.8 project.
From what I can see, the login endpoint provides the user with an access token and a refresh token which I want to use for a web app and the default method makes it very easy to get. I am using Microsoft identities and NOT JWT tokens.
However, I'm wanting to save the initial login details with the tokens to save it onto my database so I can control access of the tokens.
For example,
Similarly, I want to have a way to check if the bearer token in the API calls are valid for use by checking the database.
What I've done so far is to override the default IdentityApiEndpointRouteBuilderExtensions
so I can see how the login and refresh endpoints are working.
On the routeGroup.MapPost("/login"....)
method, I see that this piece of code is performing the logging in:
var result = await signInManager.PasswordSignInAsync(login.Email, login.Password, isPersistent, lockoutOnFailure: true);
This returns a SignInObject
which doesn't provide any details of the tokens that's just been generated.
On the routeGroup.MapPost("/refresh"...)
method, I see this line:
var refreshTokenProtector = bearerTokenOptions.Get(IdentityConstants.BearerScheme).RefreshTokenProtector;
This seems to get the refresh token which I could potentially use to check with my database and check if it's valid before proceeding any further (haven't tried it yet but will try it soon).
I am unable to find much details regarding modifying the existing identity methods so what is the best way to retrieve the access / refresh tokens on the login and refresh - or any other overridden method - so I can save this into the database for checking future requests?
EDIT: on the /login method, it states this as an official comment:
// The signInManager already produced the needed response in the form of a cookie or bearer token.
return TypedResults.Empty;
How can I get the tokens from here?
After a lot of investigating, I've come to the conclusion that it is not possible to retrieve the access token and refresh token from the login endpoint. (If this is incorrect, please feel free to write a new answer!)
What I've opted to do instead is, straight after logging in, use the bearer token to make another call to the API by passing in the access and refresh tokens in the body.
Not sure if this is the best way or the cleanest way to do it, but this provides me with the solution I need to save details about the access tokens on my DB so I can control individual bearer tokens as needed.
NOTE: I've also considered what browsermator mentioned in my question comment [the whole point of access token is to not hit the DB (or use a session variable) when verifying the session] - and this seems like a fair point.
With this in mind, I also created a middleware which checks the user object to see if their account is valid for use (since I retrieve the user object anyway) and just disable their access using the user table instead of the tokens.