From 3f9f16452f46f7e38efdeb436b28afa0dc6db777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Wed, 9 Aug 2023 17:19:58 +0200 Subject: [PATCH] Update the ASP.NET Core samples to use automatic authentication schemes = --- .../Controllers/AuthenticationController.cs | 21 ++++++++++++------- .../Controllers/HomeController.cs | 13 ++++++++---- .../Controllers/AuthenticationController.cs | 12 +++++------ .../Controllers/AuthorizationController.cs | 17 ++++++++------- 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs index 35b192d4..d8633a9c 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs @@ -1,6 +1,5 @@ using System.Security.Claims; using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Mvc; using OpenIddict.Abstractions; using OpenIddict.Client; @@ -80,7 +79,10 @@ public class AuthenticationController : Controller { // Retrieve the identity stored in the local authentication cookie. If it's not available, // this indicate that the user is already logged out locally (or has not logged in yet). - var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); + // + // For scenarios where the default authentication handler configured in the ASP.NET Core + // authentication options shouldn't be used, a specific scheme can be specified here. + var result = await HttpContext.AuthenticateAsync(); if (result is not { Principal.Identity: ClaimsIdentity identity }) { // Only allow local return URLs to prevent open redirect attacks. @@ -88,7 +90,10 @@ public class AuthenticationController : Controller } // Remove the local authentication cookie before triggering a redirection to the remote server. - await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); + // + // For scenarios where the default sign-out handler configured in the ASP.NET Core + // authentication options shouldn't be used, a specific scheme can be specified here. + await HttpContext.SignOutAsync(); // Extract the client registration identifier and retrieve the associated server configuration. // If the provider is known to support remote sign-out, ask OpenIddict to initiate a logout request. @@ -159,14 +164,14 @@ public class AuthenticationController : Controller } // Build an identity based on the external claims and that will be used to create the authentication cookie. - // + var identity = new ClaimsIdentity(authenticationType: "ExternalLogin"); + // By default, OpenIddict will automatically try to map the email/name and name identifier claims from // their standard OpenID Connect or provider-specific equivalent, if available. If needed, additional // claims can be resolved from the external identity and copied to the final authentication cookie. - var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme) - .SetClaim(ClaimTypes.Email, result.Principal.GetClaim(ClaimTypes.Email)) - .SetClaim(ClaimTypes.Name, result.Principal.GetClaim(ClaimTypes.Name)) - .SetClaim(ClaimTypes.NameIdentifier, result.Principal.GetClaim(ClaimTypes.NameIdentifier)); + identity.SetClaim(ClaimTypes.Email, result.Principal.GetClaim(ClaimTypes.Email)) + .SetClaim(ClaimTypes.Name, result.Principal.GetClaim(ClaimTypes.Name)) + .SetClaim(ClaimTypes.NameIdentifier, result.Principal.GetClaim(ClaimTypes.NameIdentifier)); // Preserve the registration identifier to be able to resolve it later. identity.SetClaim(Claims.Private.RegistrationId, result.Principal.GetClaim(Claims.Private.RegistrationId)); diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs index ac867577..76741677 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs @@ -1,7 +1,6 @@ using System.Net.Http; using System.Net.Http.Headers; using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using OpenIddict.Client; @@ -29,7 +28,9 @@ public class HomeController : Controller [Authorize, HttpPost("~/message"), ValidateAntiForgeryToken] public async Task GetMessage(CancellationToken cancellationToken) { - var token = await HttpContext.GetTokenAsync(CookieAuthenticationDefaults.AuthenticationScheme, Tokens.BackchannelAccessToken); + // For scenarios where the default authentication handler configured in the ASP.NET Core + // 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(); @@ -45,7 +46,9 @@ public class HomeController : Controller [Authorize, HttpPost("~/refresh-token"), ValidateAntiForgeryToken] public async Task RefreshToken(CancellationToken cancellationToken) { - var ticket = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); + // For scenarios where the default authentication handler configured in the ASP.NET Core + // authentication options shouldn't be used, a specific scheme can be specified here. + var ticket = await HttpContext.AuthenticateAsync(); var token = ticket?.Properties.GetTokenValue(Tokens.RefreshToken); if (string.IsNullOrEmpty(token)) { @@ -71,7 +74,9 @@ public class HomeController : Controller properties.UpdateTokenValue(Tokens.RefreshToken, result.RefreshToken); } - await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, ticket.Principal, properties); + // For scenarios where the default sign-in handler configured in the ASP.NET Core + // authentication options shouldn't be used, a specific scheme can be specified here. + await HttpContext.SignInAsync(ticket.Principal, properties); return View("Index", model: result.AccessToken); } diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthenticationController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthenticationController.cs index 38e6c5ba..404a5285 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthenticationController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthenticationController.cs @@ -1,7 +1,5 @@ using System.Security.Claims; using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using OpenIddict.Abstractions; using OpenIddict.Client.AspNetCore; @@ -53,14 +51,14 @@ public class AuthenticationController : Controller } // Build an identity based on the external claims and that will be used to create the authentication cookie. - // + var identity = new ClaimsIdentity(authenticationType: "ExternalLogin"); + // By default, OpenIddict will automatically try to map the email/name and name identifier claims from // their standard OpenID Connect or provider-specific equivalent, if available. If needed, additional // claims can be resolved from the external identity and copied to the final authentication cookie. - var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme) - .SetClaim(ClaimTypes.Email, result.Principal.GetClaim(ClaimTypes.Email)) - .SetClaim(ClaimTypes.Name, result.Principal.GetClaim(ClaimTypes.Name)) - .SetClaim(ClaimTypes.NameIdentifier, result.Principal.GetClaim(ClaimTypes.NameIdentifier)); + identity.SetClaim(ClaimTypes.Email, result.Principal.GetClaim(ClaimTypes.Email)) + .SetClaim(ClaimTypes.Name, result.Principal.GetClaim(ClaimTypes.Name)) + .SetClaim(ClaimTypes.NameIdentifier, result.Principal.GetClaim(ClaimTypes.NameIdentifier)); // Preserve the registration identifier to be able to resolve it later. identity.SetClaim(Claims.Private.RegistrationId, result.Principal.GetClaim(Claims.Private.RegistrationId)); diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs index ce5720af..fbfef061 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs @@ -64,7 +64,10 @@ public class AuthorizationController : Controller // - If the user principal can't be extracted or the cookie is too old. // - If prompt=login was specified by the client application. // - If a max_age parameter was provided and the authentication cookie is not considered "fresh" enough. - var result = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme); + // + // For scenarios where the default authentication handler configured in the ASP.NET Core + // authentication options shouldn't be used, a specific scheme can be specified here. + var result = await HttpContext.AuthenticateAsync(); if (result == null || !result.Succeeded || request.HasPrompt(Prompts.Login) || (request.MaxAge != null && result.Properties?.IssuedUtc != null && DateTimeOffset.UtcNow - result.Properties.IssuedUtc > TimeSpan.FromSeconds(request.MaxAge.Value))) @@ -123,12 +126,12 @@ public class AuthorizationController : Controller return Challenge(properties, OpenIddictClientAspNetCoreDefaults.AuthenticationScheme); } - return Challenge( - authenticationSchemes: IdentityConstants.ApplicationScheme, - properties: new AuthenticationProperties - { - RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters) - }); + // For scenarios where the default challenge handler configured in the ASP.NET Core + // authentication options shouldn't be used, a specific scheme can be specified here. + return Challenge(new AuthenticationProperties + { + RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters) + }); } // Retrieve the profile of the logged in user.