改装和授权标头

时间:2018-10-19 07:17:06

标签: c# refit

当前,我正在向请求添加一个授权标头,如下所示:

文件:SomeFile.cs

public interface ITestApi
{
    [Get("/api/test/{id}")]
    Task<string> GetTest([Header("Authorization")] string authorization, int id);

    [Get("/api/tests/")]
    Task<string> GetTests([Header("Authorization")] string authorization);
}

文件:SomeOtherFile.cs

var username = "xxx";
var password = "yyy";
var authHeader = "Basic " + Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
var baseAddress = "https://my.test.net";
ITestApi myApi = RestService.For<ITestApi>(baseAddress);

int id = 123;
var test= myApi.GetTest(authHeader, id);

var tests = myApi.GetTests(authHeader);

是否有一种全局设置authHeader的方法,这样我就不必将其作为参数传递给每个调用? (我使用的是Refit版本4.6.48)。换句话说,我希望能够进行以下呼叫:

var test= myApi.GetTest(id);

var tests = myApi.GetTests();

2 个答案:

答案 0 :(得分:2)

我找到了解决方法:

[Headers("Authorization: Basic")]
public interface ITestApi
{
    [Get("/api/test/{id}")]
    Task<string> GetTest([Header("Authorization")] string authorization, int id);

    [Get("/api/tests/")]
    Task<string> GetTests([Header("Authorization")] string authorization);
}


var username = "xxx";
var password = "yyy";
var authHeader = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
var baseAddress = "https://my.test.net";

var refitSettings = new RefitSettings()
{
    AuthorizationHeaderValueGetter = () => Task.FromResult(authHeader)
};

ITestApi myApi = RestService.For<ITestApi>(baseAddress, refitSettings);

int id = 123;
var test= myApi.GetTest(id);

var tests = myApi.GetTests();

答案 1 :(得分:2)

thd的答案对我不起作用,因为Refit当前为simply ignoring AuthorizationHeaderValueGetter,并且请求不包含身份验证标头。

我可以通过为HttpClient提供默认身份验证标头来使其正常工作:

string token = await GetTokenAsync().ConfigureAwait(false);
string endpointUrl = Environment.GetEnvironmentVariable(endpointVariable) ??
                     defaultEndpointUrl ?? DefaultEndpointUrl;

var client = new HttpClient(new HttpClientHandler())
{
    BaseAddress = new Uri(endpointUrl)
};
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

//TODO: remove as this is ignored anyway
//var refitSettings = new RefitSettings
//{
//    AuthorizationHeaderValueGetter = () => Task.FromResult($"{token}")
//};

var builder = RequestBuilder.ForType<TApiClient>();
return RestService.For(client, builder);

GetTokenAsync如下所示:

public static async Task<string> GetAccessTokenAsync()
{
    // theoretically the token could have expired during the tests, but there is very low chance
    // so returning the same token if one was generated
    lock (SyncLock)
    {
        if (!string.IsNullOrWhiteSpace(Token))
            return Token;
    }

    var client = new HttpClient();
    var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
    {
        Address = $"{IdentityServerUrl}/connect/token",
        ClientId = "MY_CLIENT_APITEST",
        ClientSecret = IdentityServerPass,
        Scope = "api.read"

    }).ConfigureAwait(false);
    tokenResponse.HttpResponse.EnsureSuccessStatusCode();

    lock (SyncLock)
    {
        Token = tokenResponse.AccessToken;
        return Token;
    }
}