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 = {