New Headers added in ocelot using DownstreamScheme Http doesn't arrive to the downstream service. For Https they arrive. #2322
Replies: 3 comments 18 replies
-
|
Hi |
Beta Was this translation helpful? Give feedback.
-
|
The flow is: App (Keycloak token) -> Ocelot API Gateway -> Authorization API (Generate new Token and return to Ocelot) -> Update Token in Ocelot API Gateway -> API Ocelot.json = https://pastebin.com/pWpEsWMj you can follow the "Sample" API Delegating Handler: namespace ApiGateway
{
public class MyReplaceTokenAuthorizationDelegatingHandler : DelegatingHandler
{
private readonly IScopeFactory _scopeFactory;
private readonly IAuthorizationApiClientFactory _authorizationApiClientFactory;
private readonly ILogger<MyReplaceTokenAuthorizationDelegatingHandler> _logger;
private readonly IHttpContextAccessor _httpContextAccessor;
private const string REDIRECT_TO_AUTHORIZATION_API_CLAIM_TYPE =
"redirectToAuthorizationApi";
public MyReplaceTokenAuthorizationDelegatingHandler(
IScopeFactory scopeFactory,
IAuthorizationApiClientFactory authorizationApiClientFactory,
ILogger<MyReplaceTokenAuthorizationDelegatingHandler> logger,
IHttpContextAccessor httpContextAccessor)
{
_scopeFactory = scopeFactory;
_authorizationApiClientFactory = authorizationApiClientFactory;
_logger = logger;
_httpContextAccessor = httpContextAccessor;
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
try
{
_logger.LogInformation($"Check if is to redirect to Authorization API");
_logger.LogInformation($"Claims {_httpContextAccessor.HttpContext.User.Claims.Count()}: " +
$"{string.Join(',', _httpContextAccessor.HttpContext!.User.Claims.Select(c => c.ToString()))}");
if (IsToRedirectAuthorization(_httpContextAccessor.HttpContext))
{
_logger.LogInformation($"Redirect to Authorization API");
await RedirectToAuthorizationApiAndUpdateTokenHeaderAsync(request);
_logger.LogInformation($"Success to redirect to Authorization API");
}
}
catch (Exception exc)
{
_logger.LogException(exc);
throw;
}
return await base.SendAsync(request, cancellationToken);
}
private bool IsToRedirectAuthorization(HttpContext httpContext)
{
IEnumerable<Claim> claims = httpContext!.User.Claims;
string? redirectClaimString =
GetStringValueFromClaimOrDefault(claims, REDIRECT_TO_AUTHORIZATION_API_CLAIM_TYPE);
_ = bool.TryParse(redirectClaimString, out bool redirect);
return redirect;
}
private string? GetStringValueFromClaimOrDefault(IEnumerable<Claim> claims, string claimType)
{
Claim? claim = claims.FirstOrDefault(x => x.Type.Equals(claimType));
string? value = null;
if (DoesClaimExist(claim))
{
value = claim!.Value;
}
return value;
}
private bool DoesClaimExist(Claim? claim)
{
return claim != null && !string.IsNullOrWhiteSpace(claim.Value);
}
private async Task RedirectToAuthorizationApiAndUpdateTokenHeaderAsync(HttpRequestMessage request)
{
AuthenticationHeaderValue authHeaderValue = request.Headers.Authorization!;
string? originalToken = authHeaderValue.Parameter;
if (!string.IsNullOrWhiteSpace(originalToken))
{
using (IDisposable scope = _scopeFactory.Create())
{
IAuthorizationApiClient authorizationApiClient = _authorizationApiClientFactory.CreateScoped(scope);
TokenResult tokenResult = await authorizationApiClient.Tokens.GenerateTokenAsync(originalToken);
DownstreamRequest downstreamRequest = _httpContextAccessor.HttpContext.Items.DownstreamRequest();
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResult.AccessToken);
bool accessToken = downstreamRequest.Headers.TryGetValues("Authorization", out IEnumerable<string>? values);
downstreamRequest.Headers.TryAddWithoutValidation("Authorization", $"Bearer {tokenResult.AccessToken}");
downstreamRequest.Headers.TryAddWithoutValidation("NewToken", $"Bearer {tokenResult.AccessToken}");
_logger.LogInformation($"New Token: {request.Headers.Authorization}");
}
}
}
}
} |
Beta Was this translation helpful? Give feedback.
-
ASP.NET theoryHere is disassembled code of the public static IApplicationBuilder UseHttpsRedirection(this IApplicationBuilder app)
{
ArgumentNullException.ThrowIfNull(app);
var serverAddressFeature = app.ServerFeatures.Get<IServerAddressesFeature>();
if (serverAddressFeature != null)
{
app.UseMiddleware<HttpsRedirectionMiddleware>(serverAddressFeature);
}
else
{
app.UseMiddleware<HttpsRedirectionMiddleware>();
}
return app;
}Thus, this method adds the var request = context.Request;
var redirectUrl = UriHelper.BuildAbsolute(
"https",
host,
request.PathBase,
request.Path,
request.QueryString);
context.Response.StatusCode = _statusCode;
context.Response.Headers.Location = redirectUrl;
_logger.RedirectingToHttps(redirectUrl);
return Task.CompletedTask;Finally, it constructs a new |
Beta Was this translation helpful? Give feedback.


Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi
I need to change the access token of requests that go to the APIs via the Ocelot API Gateway.
I try to use a DelegatingHandler or PreQueryStringBuilderMiddleware/PreAuthorizationMiddleware, and the behaviour is the same.
Both change the Header in the request, but when I receive the request in the API, it seems that it uses all the original Headers. None of the new headers that I add reach the API.
Even tried to use it via configuration using the DownstreamHeaderTransform or UpstreamHeaderTransform in the route, but nothing.
Middleware
Delegating handler
Is there some configuration that I'm missing to enable the injection of Headers?
Beta Was this translation helpful? Give feedback.
All reactions