refit
refit copied to clipboard
[BUG] AuthorizationHeaderValueGetter ignored while using RefitSettings
If I use a custom HttpClient and custom RefitSettings, the AuthorizationHeaderValueGetter gets ignored and GetTokenAsync() is never called.
RestService.For<IAccountsClient>(
new System.Net.Http.HttpClient()
{
BaseAddress = new Uri(apiIP + "Accounts"),
Timeout = timeout
}
, new RefitSettings()
{
AuthorizationHeaderValueGetter = () => GetTokenAsync()
});
This is the method in the Interface
[Headers("Authorization: Bearer")]
[Get("/EchoWithLogin")]
Task<string> EchoWithLoginAsync(string echoMessage);
Calling EchoWithLoginAsync does not add the token value to the header and the GetTokenAsync() method does not get called.
If insted I define the service as follows everything works fine, but I loose the timeout capability:
Accounts = RestService.For<IAccountsClient>(apiIP + "Accounts", new RefitSettings()
{
AuthorizationHeaderValueGetter = () => GetTokenAsync()
});
This is something I ran into the other day while trying to figure out why our logging handler wasn't calling our token provider/adding the bearer token to the headers. I believe this is intentional, although there doesn't appear to be anything in the README that implies this (that I could see). Looking at the source, however, you can see that there are a few properties on RefitSettings that will not work if you provide your own HttpClient instance:
This does actually make sense when you come to think about it; If you supply your own HttpClient instance it's not possible for Refit to set its own handler from the settings. You can only set a HttpMessageHandler from the constructors of HttpClient.
I was able to solve our issue by using RefitSettings.HttpMessageHandlerFactory instead of a supplying a HttpClient instance, as this allows the setting of the innerHandler that is passed to Refit.AuthenticatedHttpClientHandler, as can be seen here.
If I've understood what you're trying to do correctly; set a custom HttpClient.Timeout? I think you should be able to do something along the lines of this:
- Expose the
HttpClienton your API interface declaration:
interface IAccountsClient
{
// This will automagically be populated by Refit if the property exists
HttpClient Client { get; }
[Headers("Authorization: Bearer")]
[Get("/EchoWithLogin")]
Task<string> EchoWithLoginAsync(string echoMessage);
}
- Then, after creating the REST service, set the
Timeoutfor theHttpClient:
Accounts = RestService.For<IAccountsClient>(apiIP + "Accounts", new RefitSettings()
{
AuthorizationHeaderValueGetter = () => GetTokenAsync()
});
Accounts.Client.Timeout = timeout;
@chowarth is correct. Any updates to the docs to clarify this are welcome!
@chowarth Thank you, the HttpClient magic works.