add oauth2 to client

This commit is contained in:
Stanley Dimant 2024-10-29 13:05:33 +01:00
parent 6f9347917d
commit ed427de0ab
19 changed files with 1060 additions and 539 deletions

View file

@ -51,7 +51,7 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
_httpClient.Dispose();
}
public async Task<string> GetNewToken(bool isRenewal, JwtIdentifier identifier, CancellationToken token)
public async Task<string> GetNewToken(bool isRenewal, JwtIdentifier identifier, CancellationToken ct)
{
Uri tokenUri;
string response = string.Empty;
@ -63,16 +63,34 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
{
_logger.LogDebug("GetNewToken: Requesting");
tokenUri = MareAuth.AuthFullPath(new Uri(_serverManager.CurrentApiUrl
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
var secretKey = _serverManager.GetSecretKey(out _)!;
var auth = secretKey.GetHash256();
result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent(new[]
if (!_serverManager.CurrentServer.UseOAuth2)
{
tokenUri = MareAuth.AuthFullPath(new Uri(_serverManager.CurrentApiUrl
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
var secretKey = _serverManager.GetSecretKey(out _)!;
var auth = secretKey.GetHash256();
_logger.LogInformation("Sending SecretKey Request to server with auth {auth}", string.Join("", identifier.SecretKeyOrOAuth.Take(10)));
result = await _httpClient.PostAsync(tokenUri, new FormUrlEncodedContent(
[
new KeyValuePair<string, string>("auth", auth),
new KeyValuePair<string, string>("charaIdent", await _dalamudUtil.GetPlayerNameHashedAsync().ConfigureAwait(false)),
}), token).ConfigureAwait(false);
]), ct).ConfigureAwait(false);
}
else
{
tokenUri = MareAuth.AuthWithOauthFullPath(new Uri(_serverManager.CurrentApiUrl
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, tokenUri.ToString());
request.Content = new FormUrlEncodedContent([
new KeyValuePair<string, string>("uid", identifier.UID),
new KeyValuePair<string, string>("charaIdent", identifier.CharaHash)
]);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", identifier.SecretKeyOrOAuth);
_logger.LogInformation("Sending OAuth Request to server with auth {auth}", string.Join("", identifier.SecretKeyOrOAuth.Take(10)));
result = await _httpClient.SendAsync(request, ct).ConfigureAwait(false);
}
}
else
{
@ -83,7 +101,7 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
HttpRequestMessage request = new(HttpMethod.Get, tokenUri.ToString());
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _tokenCache[identifier]);
result = await _httpClient.SendAsync(request, token).ConfigureAwait(false);
result = await _httpClient.SendAsync(request, ct).ConfigureAwait(false);
}
response = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
@ -102,7 +120,7 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
Mediator.Publish(new NotificationMessage("Error refreshing token", "Your authentication token could not be renewed. Try reconnecting to Mare manually.",
NotificationType.Error));
else
Mediator.Publish(new NotificationMessage("Error generating token", "Your authentication token could not be generated. Check Mares main UI to see the error message.",
Mediator.Publish(new NotificationMessage("Error generating token", "Your authentication token could not be generated. Check Mares Main UI to see the error message.",
NotificationType.Error));
Mediator.Publish(new DisconnectedMessage());
throw new MareAuthFailureException(response);
@ -144,9 +162,20 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
return _lastJwtIdentifier;
}
jwtIdentifier = new(_serverManager.CurrentApiUrl,
playerIdentifier,
_serverManager.GetSecretKey(out _)!);
if (_serverManager.CurrentServer.UseOAuth2)
{
var oauthInfo = _serverManager.GetOAuth2(out _)!;
jwtIdentifier = new(_serverManager.CurrentApiUrl,
playerIdentifier,
oauthInfo.Value.UID, oauthInfo.Value.OAuthToken);
}
else
{
jwtIdentifier = new(_serverManager.CurrentApiUrl,
playerIdentifier,
string.Empty,
_serverManager.GetSecretKey(out _)!);
}
_lastJwtIdentifier = jwtIdentifier;
}
catch (Exception ex)
@ -205,4 +234,39 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
_logger.LogTrace("GetOrUpdate: Getting new token");
return await GetNewToken(renewal, jwtIdentifier, ct).ConfigureAwait(false);
}
public async Task<bool> TryUpdateOAuth2LoginTokenAsync()
{
var oauth2 = _serverManager.GetOAuth2(out _);
if (oauth2 == null) return false;
var handler = new JwtSecurityTokenHandler();
var jwt = handler.ReadJwtToken(oauth2.Value.OAuthToken);
if (jwt.ValidTo == DateTime.MinValue || jwt.ValidTo.Subtract(TimeSpan.FromDays(7)) > DateTime.Now)
return true;
if (jwt.ValidTo < DateTime.UtcNow)
return false;
var tokenUri = MareAuth.RenewOAuthTokenFullPath(new Uri(_serverManager.CurrentApiUrl
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, tokenUri.ToString());
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", oauth2.Value.OAuthToken);
_logger.LogInformation("Sending Request to server with auth {auth}", string.Join("", oauth2.Value.OAuthToken.Take(10)));
var result = await _httpClient.SendAsync(request).ConfigureAwait(false);
if (!result.IsSuccessStatusCode)
{
_logger.LogWarning("Could not renew OAuth2 Login token, error code {error}", result.StatusCode);
return false;
}
var newToken = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
_serverManager.CurrentServer.OAuthToken = newToken;
_serverManager.Save();
return true;
}
}