Intility.Extensions.HttpClientAuthorization 2025.5.7-preview-1

This is a prerelease version of Intility.Extensions.HttpClientAuthorization.
dotnet add package Intility.Extensions.HttpClientAuthorization --version 2025.5.7-preview-1
                    
NuGet\Install-Package Intility.Extensions.HttpClientAuthorization -Version 2025.5.7-preview-1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Intility.Extensions.HttpClientAuthorization" Version="2025.5.7-preview-1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Intility.Extensions.HttpClientAuthorization" Version="2025.5.7-preview-1" />
                    
Directory.Packages.props
<PackageReference Include="Intility.Extensions.HttpClientAuthorization" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Intility.Extensions.HttpClientAuthorization --version 2025.5.7-preview-1
                    
#r "nuget: Intility.Extensions.HttpClientAuthorization, 2025.5.7-preview-1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Intility.Extensions.HttpClientAuthorization@2025.5.7-preview-1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Intility.Extensions.HttpClientAuthorization&version=2025.5.7-preview-1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Intility.Extensions.HttpClientAuthorization&version=2025.5.7-preview-1&prerelease
                    
Install as a Cake Tool

Intility.Extensions.HttpClientAuthorization

Extensions to help authenticate System.Net.Http.HttpClients and handle key rotation in web services and backends using delegated authentication scenarios.

Motivation

Microsoft Secure App Model requires a delegated access paradigm where service → service authentication scenarios are difficult to handle. The system administrator would need to sign in on behalf of the service and handle access-token and refresh-token rotation in the background.

This package aims to ease the pain with automatic token acquisition and rotation as well as renewal of Authorization headers on HttpClients respectively.

Installation

Install Intility.Extensions.HttpClientAuthorization with the NuGet package manager in Visual Studio or via CLI:

dotnet add package Intility.Extensions.HttpClientAuthorization

Configuring the http clients

The client configuration should be stored in appsettings.json and extracted at runtime.

appsettings.json

{
  "Clients": {
    "PartnerCenter": {
      "TenantId": "<your-tenant-id>",
      "ClientId": "<appid-with-delegated-permission>",
      "Scopes": [ "https://api.partnercenter.microsoft.com/user_impersonation" ]
    },
    "Graph": {
      "TenantId": "<your-tenant-id>",
      "ClientId": "<appid-with-delegated-permission>",
      "Scopes": [ "https://graph.microsoft.com/User.Read" ]
    }
  }
}

Program.cs / Startup.cs

services
    .AddHttpClient<IGraphService, GraphService>()
    .AddClientAuthentication(auth => 
        auth.UseDeviceCodeDelegation(options =>
            Configuration.GetSection("Clients:PartnerCenter").Bind(options)));

Notice that we are instrumenting a client for a specific service. This will ensure that when the GraphService requires an HttpClient in its contructor we will provide the configured client. This examples uses a TypedClient pattern, but other patters are also available. See Make HTTP requests using IHttpClientFactory in ASP.NET Core.

.AddClientAuthentication() ensures that your configuration in incorporated in the authentication policy. UseDeviceCodeDelegation is useful because it requires no browser on the host but instead prompts for a one-time-password for the system administrator to authenticate the client on another process/host.


NOTE

Authentication challenge will be prompted via the AspNet Logging mechanism and should output to the Console by default.


Required depdendencies

To store and protect the credentials the system uses configurable components from the AspNet ecosystem. IDistributedCache for storage and DataProtection for key protection.

IDistributedCache

IDistributedCache has a default InMemory implementation but can (and should) be configured to store cache off process. Some out-of-the box implementations can be installed with its own package:

DataProtection

To ensure that the cache is encrypted at rest we're using the DataProtection extensions to protect/unprotect the cache payload in the cache. Protection method is configurable with additional packages. See Configure ASP.NET Core Data Protection for more information.

Using the clients

The authorization negotiation and acquisition is handled inside the HttpMessageHandler and should not interfere with normal use. See examples below or a complete example in the /samples folder.

GraphService.cs


public interface IGraphService
{
    Task<string> GetMePayload();
}

public class GraphService : IGraphService
{
    private readonly HttpClient _httpClient;

    /// <summary>
    /// Receives a HttpClient from the dependency container.
    /// This client is configured with authentication policy 
    /// in Startup.cs
    /// </summary>
    /// <param name="httpClient"></param>
    public GraphService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<string> GetMePayload()
    {
        var response = await _httpClient.GetAsync("https://graph.microsoft.com/v1.0/me");
        var json = await response.Content.ReadAsStringAsync();

        return json;
    }
}

GraphExampleController.cs

[ApiController]
[Route("[controller]")]
public class GraphExampleController : ControllerBase
{
    private readonly IGraphService _graphService;

    public GraphExampleController(IGraphService graphService)
    {
        _graphService = graphService;
    }

    [HttpGet]
    public async Task<IActionResult> Get()
    {
        var content = await _graphService.GetMePayload();
        return Content(content, "application/json");
    }
}
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2025.5.7-preview-1 147 5/7/2025
1.0.3 430 5/7/2025
1.0.2 144 5/7/2025
1.0.1-preview-9 140 5/6/2025
1.0.0-preview-9 137 5/6/2025
1.0.0-preview-8 136 5/6/2025
1.0.0-preview-7 135 5/6/2025
1.0.0-preview-6 143 5/6/2025
1.0.0-preview-5 141 5/5/2025
1.0.0-preview-4 135 5/5/2025
1.0.0-preview-3 140 5/5/2025