asynchronous - Using OAuth2 in ODataV4getting Token asynchronously - Stack Overflow

I've got an OData connected service for V4 generated through a metadata file.Since the service re

I've got an OData connected service for V4 generated through a metadata file.

Since the service requires OAuth2, I have to obtain the token asynchronously from a web server before sent any message.

In order to achieve that, I've configured the service applying DI pattern using Microsoft.OData.Extensions.Client:

services.AddODataClient(nameof(ApiServices))
        .ConfigureODataClient(config =>
              {
                 config.AddAndUpdateResponsePreference = DataServiceResponsePreference.IncludeContent;
                 config.Format.UseJson();
                 config.MergeOption = MergeOption.OverwriteChanges;
              })
        .AddHttpClient()
        .AddHttpMessageHandler<BearerTokenAuthHandler>()
        .Services
        .AddTransient<BearerTokenAuthHandler>()
        .AddTransient<ApiServices>()
        .AddTransient<IServiceAuthentication, ApiServices>();

HttpMessageHandler is:

internal partial class BearerTokenAuthHandler : DelegatingHandler
{
      IAccessTokenProvider _tokenClient;

      public BearerTokenAuthHandler(IServiceAuthentication service)
      {
         _tokenClient = service.AuthenticationProvider.AccessTokenProvider;
      }

      protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
      {
         string url = string.Format(EntraApps.BcAuthorizationUrl, EntraApps.TenantId);

         string token = await _tokenClient.GetAuthorizationTokenAsync(new Uri(url), null, cancellationToken);
         request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);

         HttpRequestOptionsKey<string> option = new HttpRequestOptionsKey<string>("tenant");
         request.Options.Set(option, EntraApps.BcTenantId);

         return await base.SendAsync(request, cancellationToken);
      }
}

Problem is: BearerTokenAuthHandler is not instantiated when after building any query, ExecuteAsync() is executed. So, no authorisation happens, and no data is retrieved and a DataServiceClientException is thrown ("Unauthorised / The credentials provided are incorrect"):

ApiServices service = ServiceProvider.GetService<ApiServices>();

IEnumerable<Company> companies = await service .Companies.ExecuteAsync();

However, if I build same message using the query building and HttpClientFactory from the service instance, there's no problem. Authorization is Ok and data is retrieved from the server:

ApiServices service = ServiceProvider.GetService<ApiServices>();
HttpClient client = service.HttpClientFactory.CreateClient(nameof(ApiServices));

Uri uri = service.Companies.RequestUri;

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
HttpResponseMessage response = await client.SendAsync(request);

Is something wrong with my code? It seems that OData ExecuteAsync() doesn't use HttpClientFactory after all.

SendingRequest2 event is of no use, since it's synchronous.

Any suggestion will be appreciated.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742402440a4437180.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信