private async Task <string> FetchJwtFromUrl(ClientAuthorizationSettings authSettings, CancellationToken cancellationToken = default) { InternalContract.RequireNotNull(authSettings, nameof(authSettings)); FulcrumAssert.IsNotNullOrWhiteSpace(authSettings.PostUrl, null, "Expected a Url to Post to"); FulcrumAssert.IsNotNullOrWhiteSpace(authSettings.PostBody, null, "Expected a Body to post to the url"); FulcrumAssert.IsNotNullOrWhiteSpace(authSettings.ResponseTokenJsonPath, null, "Expected a Json path to the token in the response"); var httpRequest = new HttpRequestMessage { Method = HttpMethod.Post, RequestUri = new Uri(authSettings.PostUrl), Content = new StringContent(authSettings.PostBody, Encoding.UTF8, authSettings.PostContentType) }; var response = ""; try { var httpResponse = await HttpClient.SendAsync(httpRequest, cancellationToken); if (httpResponse == null || !httpResponse.IsSuccessStatusCode) { Log.LogError($"Error fetching token from '{authSettings.PostUrl}' with json path '{authSettings.ResponseTokenJsonPath}'. Status code: '{httpResponse?.StatusCode}'."); return(null); } FulcrumAssert.IsNotNull(httpResponse.Content); await httpResponse.Content.LoadIntoBufferAsync(); response = await httpResponse.Content.ReadAsStringAsync(); var result = JToken.Parse(response); FulcrumAssert.IsNotNull(result); var jwtToken = result.SelectToken(authSettings.ResponseTokenJsonPath)?.ToObject <string>(); FulcrumAssert.IsNotNull(jwtToken); return(jwtToken); } catch (Exception e) { Log.LogError($"Error fetching token from '{authSettings.PostUrl}' with json path '{authSettings.ResponseTokenJsonPath}' on response '{response}'. Error message: {e.Message}", e); return(null); } }
/// <inheritdoc /> public async Task <AuthorizationToken> GetAuthorizationForClientAsync(Tenant tenant, ClientAuthorizationSettings authSettings, string client, CancellationToken cancellationToken = default) { var cacheKey = $"{tenant}/{client}"; if (_authCache[cacheKey] is AuthorizationToken authorization) { return(authorization); } try { string token, tokenType; switch (authSettings.AuthorizationType) { case ClientAuthorizationSettings.AuthorizationTypeEnum.None: return(null); case ClientAuthorizationSettings.AuthorizationTypeEnum.Basic: FulcrumAssert.IsNotNullOrWhiteSpace(authSettings.Username, null, "Expected a Basic Auth Username"); FulcrumAssert.IsNotNull(authSettings.Password, null, "Expected a Basic Auth Password"); token = Base64Encode($"{authSettings.Username}:{authSettings.Password}"); tokenType = "Basic"; break; case ClientAuthorizationSettings.AuthorizationTypeEnum.BearerToken: FulcrumAssert.IsNotNullOrWhiteSpace(authSettings.Token, "Expected a Bearer token"); token = authSettings.Token; tokenType = "Bearer"; break; case ClientAuthorizationSettings.AuthorizationTypeEnum.JwtFromUrl: token = await FetchJwtFromUrl(authSettings, cancellationToken); tokenType = "Bearer"; break; case ClientAuthorizationSettings.AuthorizationTypeEnum.NexusPlatformService: var authToken = await FetchJwtFromPlatformTokenRefresher(cancellationToken); token = authToken?.AccessToken; tokenType = authToken?.Type; break; default: throw new ArgumentException($"Unknown Authorization Type: '{authSettings.AuthorizationType}'"); } if (string.IsNullOrWhiteSpace(token)) { throw new FulcrumAssertionFailedException($"Client authorization of type '{authSettings.AuthorizationType}' resulted in an empty token."); } authorization = new AuthorizationToken { Type = tokenType, Token = token }; _authCache.Set(cacheKey, authorization, DateTimeOffset.Now.AddMinutes(authSettings.TokenCacheInMinutes)); } catch (Exception e) { Log.LogCritical($"Could not handle Authentication for client '{client}' in tenant '{tenant}'.", e); throw; } return(authorization); }