diff --git a/Directory.Build.targets b/Directory.Build.targets
index 93a20cbe5..ff177a8a1 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -117,6 +117,7 @@
$(DefineConstants);SUPPORTS_CERTIFICATE_LOADER
$(DefineConstants);SUPPORTS_JSON_ELEMENT_DEEP_EQUALS
$(DefineConstants);SUPPORTS_JSON_ELEMENT_PROPERTY_COUNT
+ $(DefineConstants);SUPPORTS_KEYED_HTTP_CLIENT_RESOLUTION
$(DefineConstants);SUPPORTS_TYPE_DESCRIPTOR_TYPE_REGISTRATION
$(DefineConstants);SUPPORTS_X509_CHAIN_POLICY_CLONING
$(DefineConstants);SUPPORTS_X509_CHAIN_POLICY_VERIFICATION_TIME_MODE
diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/HomeController.cs b/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/HomeController.cs
index fb52619ca..bc6fc8121 100644
--- a/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/HomeController.cs
+++ b/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/HomeController.cs
@@ -6,6 +6,7 @@
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using OpenIddict.Client;
@@ -15,23 +16,12 @@
namespace OpenIddict.Sandbox.AspNet.Client.Controllers;
-public class HomeController : Controller
+public class HomeController([FromKeyedServices("ApiClient")] HttpClient client, OpenIddictClientService service) : Controller
{
- private readonly IHttpClientFactory _httpClientFactory;
- private readonly OpenIddictClientService _service;
-
- public HomeController(
- IHttpClientFactory httpClientFactory,
- OpenIddictClientService service)
- {
- _httpClientFactory = httpClientFactory;
- _service = service;
- }
-
[HttpGet, Route("~/")]
public async Task Index(CancellationToken cancellationToken) => View(new IndexViewModel
{
- Providers = from registration in await _service.GetClientRegistrationsAsync(cancellationToken)
+ Providers = from registration in await service.GetClientRegistrationsAsync(cancellationToken)
where !string.IsNullOrEmpty(registration.ProviderName)
where !string.IsNullOrEmpty(registration.ProviderDisplayName)
select registration
@@ -45,9 +35,7 @@ public async Task GetMessage(CancellationToken cancellationToken)
var result = await context.Authentication.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationType);
var token = result.Properties.Dictionary[Tokens.BackchannelAccessToken];
- using var client = _httpClientFactory.CreateClient();
-
- using var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:44349/api/message");
+ using var request = new HttpRequestMessage(HttpMethod.Get, "api/message");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
using var response = await client.SendAsync(request, cancellationToken);
@@ -56,7 +44,7 @@ public async Task GetMessage(CancellationToken cancellationToken)
return View("Index", new IndexViewModel
{
Message = await response.Content.ReadAsStringAsync(),
- Providers = from registration in await _service.GetClientRegistrationsAsync(cancellationToken)
+ Providers = from registration in await service.GetClientRegistrationsAsync(cancellationToken)
where !string.IsNullOrEmpty(registration.ProviderName)
where !string.IsNullOrEmpty(registration.ProviderDisplayName)
select registration
@@ -75,7 +63,7 @@ public async Task RefreshToken(CancellationToken cancellationToken
return new HttpStatusCodeResult(400);
}
- var result = await _service.AuthenticateWithRefreshTokenAsync(new()
+ var result = await service.AuthenticateWithRefreshTokenAsync(new()
{
CancellationToken = cancellationToken,
RefreshToken = token,
@@ -99,7 +87,7 @@ public async Task RefreshToken(CancellationToken cancellationToken
return View("Index", new IndexViewModel
{
Message = result.AccessToken,
- Providers = from registration in await _service.GetClientRegistrationsAsync(cancellationToken)
+ Providers = from registration in await service.GetClientRegistrationsAsync(cancellationToken)
where !string.IsNullOrEmpty(registration.ProviderName)
where !string.IsNullOrEmpty(registration.ProviderDisplayName)
select registration
diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs b/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs
index 3e9e1b592..a347ed4b2 100644
--- a/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs
+++ b/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs
@@ -1,4 +1,5 @@
using System;
+using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Mvc;
using Autofac;
@@ -101,6 +102,16 @@ public void Configuration(IAppBuilder app)
});
});
+ // Register a named HTTP client that will be used to call the demo resource API.
+ services.AddHttpClient("ApiClient")
+ .ConfigureHttpClient(static client => client.BaseAddress = new Uri("https://localhost:44349/"));
+
+ services.AddKeyedScoped("ApiClient", static (provider, name) =>
+ {
+ var factory = provider.GetRequiredService();
+ return factory.CreateClient((string) name!);
+ });
+
// Create a new Autofac container and import the OpenIddict services.
var builder = new ContainerBuilder();
builder.Populate(services);
diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs
index 0f5db3389..5c1efcda0 100644
--- a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs
+++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs
@@ -10,23 +10,12 @@
namespace OpenIddict.Sandbox.AspNetCore.Client.Controllers;
-public class HomeController : Controller
+public class HomeController([FromKeyedServices("ApiClient")] HttpClient client, OpenIddictClientService service) : Controller
{
- private readonly IHttpClientFactory _httpClientFactory;
- private readonly OpenIddictClientService _service;
-
- public HomeController(
- IHttpClientFactory httpClientFactory,
- OpenIddictClientService service)
- {
- _httpClientFactory = httpClientFactory;
- _service = service;
- }
-
[HttpGet("~/")]
public async Task Index(CancellationToken cancellationToken) => View(new IndexViewModel
{
- Providers = from registration in await _service.GetClientRegistrationsAsync(cancellationToken)
+ Providers = from registration in await service.GetClientRegistrationsAsync(cancellationToken)
where !string.IsNullOrEmpty(registration.ProviderName)
where !string.IsNullOrEmpty(registration.ProviderDisplayName)
select registration
@@ -39,8 +28,6 @@ public async Task GetMessage(CancellationToken cancellationToken)
// authentication options shouldn't be used, a specific scheme can be specified here.
var token = await HttpContext.GetTokenAsync(Tokens.BackchannelAccessToken);
- using var client = _httpClientFactory.CreateClient("ApiClient");
-
using var request = new HttpRequestMessage(HttpMethod.Get, "api/message");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -50,7 +37,7 @@ public async Task GetMessage(CancellationToken cancellationToken)
return View("Index", new IndexViewModel
{
Message = await response.Content.ReadAsStringAsync(),
- Providers = from registration in await _service.GetClientRegistrationsAsync(cancellationToken)
+ Providers = from registration in await service.GetClientRegistrationsAsync(cancellationToken)
where !string.IsNullOrEmpty(registration.ProviderName)
where !string.IsNullOrEmpty(registration.ProviderDisplayName)
select registration
@@ -74,7 +61,7 @@ public async Task RefreshToken(CancellationToken cancellationToken
return BadRequest();
}
- var result = await _service.AuthenticateWithRefreshTokenAsync(new()
+ var result = await service.AuthenticateWithRefreshTokenAsync(new()
{
CancellationToken = cancellationToken,
RefreshToken = token,
@@ -100,7 +87,7 @@ public async Task RefreshToken(CancellationToken cancellationToken
return View("Index", new IndexViewModel
{
Message = result.AccessToken,
- Providers = from registration in await _service.GetClientRegistrationsAsync(cancellationToken)
+ Providers = from registration in await service.GetClientRegistrationsAsync(cancellationToken)
where !string.IsNullOrEmpty(registration.ProviderName)
where !string.IsNullOrEmpty(registration.ProviderDisplayName)
select registration
diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs
index 3a6392ddf..002f08f02 100644
--- a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs
+++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs
@@ -1,3 +1,4 @@
+using System.Net.Http;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Authentication.Cookies;
@@ -198,6 +199,9 @@ public void ConfigureServices(IServiceCollection services)
// access tokens, the client certificate MUST be attached to outgoing HTTP requests
// and the mTLS subdomain (for which TLS client authentication is enabled) MUST be used.
services.AddHttpClient("ApiClient")
+#if SUPPORTS_KEYED_HTTP_CLIENT_RESOLUTION
+ .AddAsKeyed()
+#endif
#if SUPPORTS_PEM_ENCODED_KEY_IMPORT
.ConfigureHttpClient(static client => client.BaseAddress = new Uri("https://mtls.dev.localhost:44395/"))
.ConfigurePrimaryHttpMessageHandler(static () => new HttpClientHandler
@@ -209,6 +213,14 @@ public void ConfigureServices(IServiceCollection services)
.ConfigureHttpClient(static client => client.BaseAddress = new Uri("https://localhost:44395/"));
#endif
+#if !SUPPORTS_KEYED_HTTP_CLIENT_RESOLUTION
+ services.AddKeyedScoped("ApiClient", static (provider, name) =>
+ {
+ var factory = provider.GetRequiredService();
+ return factory.CreateClient((string) name!);
+ });
+#endif
+
services.AddMvc();
}
diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs
index b31a0b5cb..844e42c75 100644
--- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs
+++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs
@@ -153,6 +153,7 @@ static async Task RegisterApplicationsAsync(IServiceProvider provider)
{
ApplicationType = ApplicationTypes.Web,
ClientId = "mvc",
+ ClientSecret = "emCimpdc9SeOaZzN5jzm4_eek-STF6VenfVlKO1_qt0",
ClientType = ClientTypes.Confidential,
ConsentType = ConsentTypes.Systematic,
DisplayName = "MVC client application",
@@ -206,8 +207,6 @@ static async Task RegisterApplicationsAsync(IServiceProvider provider)
"""))
}
},
-#else
- ClientSecret = "emCimpdc9SeOaZzN5jzm4_eek-STF6VenfVlKO1_qt0",
#endif
RedirectUris =
{