未经授权 401 错误在使用 C# 中的 httpClient 时发生。

huangapple go评论71阅读模式
英文:

unauthorized 401 error while using httpClient in C#

问题

Here is the translated code:

我正在使用httpClient调用受Azure AAD保护的WebApi
我调用MSAL库来获取令牌并设置如下标头

private async void SetHeaders(HttpClient HttpClientObj)
{
    IConfidentialClientApplication app;
    app = ConfidentialClientApplicationBuilder.Create(_configurationSettings.TestAppClientId)
                                .WithClientSecret(_configurationSettings.TestAppClientSecret)
                                .WithAuthority(new Uri(_configurationSettings.TestAppInstance + _configurationSettings.TestAppTenantId))
                                .Build();

    AuthenticationResult result = null;

    IEnumerable<string> scopes = new List<string>() { _configurationSettings.TestAppAuthScope };
    try
    {
        result = await app.AcquireTokenForClient(scopes)
                          .ExecuteAsync();
    }
    catch (MsalServiceException ex)
    {
        _logger.LogError("Exception Message: {ex}");
    }

    var defaultRequestHeaders = HttpClientObj.DefaultRequestHeaders;
    defaultRequestHeaders.Clear();

    if (defaultRequestHeaders.Accept == null || !defaultRequestHeaders.Accept.Any(m => m.MediaType == "application/json"))
    {
        HttpClientObj.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    try
    {
        defaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
    }
    catch (Exception ex)
    {
        _logger.LogError("Exception Message: {ex}");
    }
}

private async Task<HttpResponseMessage> CallTestAppAPIToGetDataAsync(string testAppUri)
{
        HttpResponseMessage response = null;

        HttpClient testHttpClientObj = new HttpClient();
        SetHeaders(testHttpClientObj);

        response = await testHttpClientObj.GetAsync(requestUri: gridstateUri);

        return response;
}

Please note that code translation might be context-dependent, and it's important to ensure that the variables and configuration settings match your specific implementation.

英文:

I am using httpClient to call a WebApi protected with Azure AAD.
I call the MSAL library to fetch the token and set up the headers like below.

        private async void SetHeaders(HttpClient HttpClientObj)
        {
            IConfidentialClientApplication app;
            app = ConfidentialClientApplicationBuilder.Create(_configurationSettings.TestAppClientId)
                                    .WithClientSecret(_configurationSettings.TestAppClientSecret)
                                    .WithAuthority(new Uri(_configurationSettings.TestAppInstance + _configurationSettings.TestAppTenantId))
                                    .Build();

            AuthenticationResult result = null;

            IEnumerable&lt;string&gt; scopes = new List&lt;string&gt;() { _configurationSettings.TestAppAuthScope };
            try
            {
                result = await app.AcquireTokenForClient(scopes)
                                  .ExecuteAsync();
            }
            catch (MsalServiceException ex)
            {
                _logger.LogError(&quot;Exception Message: {ex}&quot;);
            }

            var defaultRequestHeaders = HttpClientObj.DefaultRequestHeaders;
            defaultRequestHeaders.Clear();

            if (defaultRequestHeaders.Accept == null || !defaultRequestHeaders.Accept.Any(m =&gt; m.MediaType == &quot;application/json&quot;))
            {
                HttpClientObj.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(&quot;application/json&quot;));
            }

            try
            {
                defaultRequestHeaders.Authorization = new AuthenticationHeaderValue(&quot;Bearer&quot;, result.AccessToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(&quot;Exception Message: {ex}&quot;);
            }
        }
        private async Task&lt;HttpResponseMessage&gt; CallTestAppAPIToGetDataAsync(string testAppUri)
        {
                HttpResponseMessage response = null;

                HttpClient testHttpClientObj = new HttpClient();
                SetHeaders(testHttpClientObj);

                response = await testHttpClientObj.GetAsync(requestUri: gridstateUri);

                return response;
        }

I added one breakpoint in line where the httpClientObj calls the API and I can see the Authorization token with the correct value.
When I try to hit the same uri with in postman with the same token it works fine, but here it gives 401 Unauthorized.

                response = await testHttpClientObj.GetAsync(requestUri: gridstateUri);

未经授权 401 错误在使用 C# 中的 httpClient 时发生。

答案1

得分: 3

你已经将SetHeaders方法声明为async,并在内部使用await,所以尝试通过将声明更改为async Task来修复你的代码。

private async Task SetHeaders(HttpClient HttpClientObj)
{
    ...
}

然后通过await SetHeaders(testHttpClientObj)等待此方法的结果,否则程序将在等待任务完成之前继续执行。

英文:

You have declared SetHeaders method as async and using await inside, so try fixing your code by changing declaration to async Task

private async Task SetHeaders(HttpClient HttpClientObj)
{
    ...
}

and then awaiting the result of this method by await SetHeaders(testHttpClientObj) otherwise the program continues without waiting for the task to complete

huangapple
  • 本文由 发表于 2023年5月17日 15:59:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76269774.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定