I need my app to support custom authentication against our private database, and following the advices on Adrian Hall book here https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter2/custom/ I got no problem authenticating my users. The problem comes when I need to refresh the access token. As I'm forced to stay with custom auth, I have the following questions:
1) Should I call MobileServicesClient.RefreshUserAsync(), and if so, what kind of endpoint should I implement on the server? Will it reissue another token every time, invalidating the old? When should be the refresh call be made?
2) I've read about using a never-expiring refresh token, but I can't really find a sample implementation, or instructions on how to implement it in a custom auth scenario, could someone point me to the right direction?
Many thanks in advance
Should I call MobileServicesClient.RefreshUserAsync(), and if so, what kind of endpoint should I implement on the server? Will it reissue another token every time, invalidating the old? When should be the refresh call be made?
I have checked the method RefreshUserAsync
from Microsoft.WindowsAzure.Mobile.dll
which would send a get request against the /.auth/refresh
endpoint for refreshing the access token with the provider for your logged in user. Since you are using custom authentication, you could not use this method for refreshing the authenticationToken
.
I've read about using a never-expiring refresh token, but I can't really find a sample implementation, or instructions on how to implement it in a custom auth scenario, could someone point me to the right direction?
When using the CreateToken
method from AppServiceLoginHandler, you could specify the lifetime
as null
, then you would retrieve a never-expiring authenticationToken
as follows:
JwtSecurityToken token = AppServiceLoginHandler.CreateToken(claims, signingKey, audience, issuer,null);
Additionally, you could try to build your endpoint for creating new token based on the old valid token as follows:
[Route(".auth/login/customRefreshToken")]
public IHttpActionResult RefreshToken([FromBody] RefreshTokenInput body)
{
string tokenString = body.AuthenticationToken;
try
{
var jwtSecurityToken = new JwtSecurityToken(tokenString);
JwtSecurityToken token = AppServiceLoginHandler.CreateToken(jwtSecurityToken.Claims, signingKey, audience, issuer, TimeSpan.FromDays(30));
return Ok(new LoginResult()
{
AuthenticationToken = token.RawData
});
}
catch (Exception e)
{
return BadRequest("$Error = {e.Message}, StackTrace = {e.StackTrace}");
}
}
Note: For your mobile client, you could use MobileServiceClient.InvokeApiAsync
for retrieving the new token, then parse the authenticationToken
and update it to MobileServiceClient.CurrentUser.MobileServiceAuthenticationToken
.
RESULT