Reputation: 24395
I'm using a C# Refit client to have my services talk to one another via http.
I'm trying to send a Bearer token through the Authorization header, but according to the error message, it's not setting the AZ header in the request (see bottom). I've tried setting it through providing all headers, and using the [Authorize]
attribute, and all the other methods they describe in their readme.
Here is my Refit client api call definition:
[Post(PresentationsBasePath + "/{presentationId}/cart")]
Task AddItemToCartAsync(long presentationId, ShoppingCartItemView item, [HeaderCollection] IDictionary<string, string> headers);
//calling it here:
await _api.AddItemToCartAsync(presentationId, item, GetTokenHeader(presentationId, token));
private Dictionary<string, string> GetTokenHeader(long presentationId, string token) => new()
{
["pres_id"] = presentationId.ToString(),
[HeaderNames.Authorization] = $"Bearer {token}",
};
However, I'm getting a 401, and looking at the Refit.ApiException
that's thrown, the RequestMessage.Headers
does not contain the Authorization header.
Here's how I'm registering my refit api IPresentationsApi
. I'm not doing anything relating to auth in the DI configuration
var refitSettings = GetRefitSettings();
void Configure<T>() where T : class => services
.AddRefitClient<T>()
.ConfigureHttpClient(ConfigureHttpClient);
Configure<IMarsPresentationApi>();
//other apis configured below
private static void ConfigureHttpClient(IServiceProvider sp, HttpClient client)
{
var config = sp.GetRequiredService<IMarsConfiguration>();
if (config.BaseUrl == null)
throw new InvalidOperationException("Mars:BaseUrl must be configured");
client.BaseAddress = new Uri(config.BaseUrl);
}
Error shown here- you can see I get 401, and AZ header is not set in the request:
What am I doing wrong? How do I get it to send the AZ header?
Upvotes: 4
Views: 5752
Reputation: 543
This discussion continued on a GitHub issue for Refit. Somebody usefully pointed out that by default Authorization headers get stripped off when HttpClient follows a redirect - https://github.com/reactiveui/refit/issues/1374#issuecomment-1212776451.
I also hit the same issue described. After reading the suggestion in the GitHub issue discussion I configured my HttpClient instance that disabled auto redirects.
var httpClient = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = false })
This confirmed that the server API was returning 301-Moved Permanently responses to API endpoints that looked correct from the API documentation I had been given.
Looking at how I had configured my API endpoints they were configured like /{presentationId}/cart
without slash at the end.
I updated the endpoints to end with a final slash /{presentationId}/cart/
and this stopped the server redirects being returned.
Upvotes: 0
Reputation: 2000
first try:
services.AddRefitClient<T>(new RefitSettings { AuthorizationHeaderValueGetter = () => Task.FromResult("TestToken") }).ConfigureHttpClient(ConfigureHttpClient);
second try:
services.AddRefitClient<T>().ConfigureHttpClient(ConfigureHttpClient).AddHttpMessageHandler<AuthorizationMessageHandler>();
where:
public class AuthorizationMessageHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancelToken)
{
HttpRequestHeaders headers = request.Headers;
AuthenticationHeaderValue authHeader = headers.Authorization;
if (authHeader != null)
headers.Authorization = new AuthenticationHeaderValue(authHeader.Scheme, "TestToken");
return await base.SendAsync(request, cancelToken);
}
}
Upvotes: 1