Browse Source

Update the ASP.NET Core samples to use automatic authentication schemes

=
pull/1862/head
Kévin Chalet 3 years ago
parent
commit
3f9f16452f
  1. 21
      sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs
  2. 13
      sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs
  3. 12
      sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthenticationController.cs
  4. 17
      sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs

21
sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs

@ -1,6 +1,5 @@
using System.Security.Claims; using System.Security.Claims;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using OpenIddict.Client; 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, // 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). // 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 }) if (result is not { Principal.Identity: ClaimsIdentity identity })
{ {
// Only allow local return URLs to prevent open redirect attacks. // 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. // 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. // 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. // 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. // 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 // 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 // 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. // claims can be resolved from the external identity and copied to the final authentication cookie.
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme) identity.SetClaim(ClaimTypes.Email, result.Principal.GetClaim(ClaimTypes.Email))
.SetClaim(ClaimTypes.Email, result.Principal.GetClaim(ClaimTypes.Email)) .SetClaim(ClaimTypes.Name, result.Principal.GetClaim(ClaimTypes.Name))
.SetClaim(ClaimTypes.Name, result.Principal.GetClaim(ClaimTypes.Name)) .SetClaim(ClaimTypes.NameIdentifier, result.Principal.GetClaim(ClaimTypes.NameIdentifier));
.SetClaim(ClaimTypes.NameIdentifier, result.Principal.GetClaim(ClaimTypes.NameIdentifier));
// Preserve the registration identifier to be able to resolve it later. // Preserve the registration identifier to be able to resolve it later.
identity.SetClaim(Claims.Private.RegistrationId, result.Principal.GetClaim(Claims.Private.RegistrationId)); identity.SetClaim(Claims.Private.RegistrationId, result.Principal.GetClaim(Claims.Private.RegistrationId));

13
sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs

@ -1,7 +1,6 @@
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using OpenIddict.Client; using OpenIddict.Client;
@ -29,7 +28,9 @@ public class HomeController : Controller
[Authorize, HttpPost("~/message"), ValidateAntiForgeryToken] [Authorize, HttpPost("~/message"), ValidateAntiForgeryToken]
public async Task<ActionResult> GetMessage(CancellationToken cancellationToken) public async Task<ActionResult> 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(); using var client = _httpClientFactory.CreateClient();
@ -45,7 +46,9 @@ public class HomeController : Controller
[Authorize, HttpPost("~/refresh-token"), ValidateAntiForgeryToken] [Authorize, HttpPost("~/refresh-token"), ValidateAntiForgeryToken]
public async Task<ActionResult> RefreshToken(CancellationToken cancellationToken) public async Task<ActionResult> 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); var token = ticket?.Properties.GetTokenValue(Tokens.RefreshToken);
if (string.IsNullOrEmpty(token)) if (string.IsNullOrEmpty(token))
{ {
@ -71,7 +74,9 @@ public class HomeController : Controller
properties.UpdateTokenValue(Tokens.RefreshToken, result.RefreshToken); 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); return View("Index", model: result.AccessToken);
} }

12
sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthenticationController.cs

@ -1,7 +1,5 @@
using System.Security.Claims; using System.Security.Claims;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using OpenIddict.Client.AspNetCore; 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. // 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 // 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 // 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. // claims can be resolved from the external identity and copied to the final authentication cookie.
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme) identity.SetClaim(ClaimTypes.Email, result.Principal.GetClaim(ClaimTypes.Email))
.SetClaim(ClaimTypes.Email, result.Principal.GetClaim(ClaimTypes.Email)) .SetClaim(ClaimTypes.Name, result.Principal.GetClaim(ClaimTypes.Name))
.SetClaim(ClaimTypes.Name, result.Principal.GetClaim(ClaimTypes.Name)) .SetClaim(ClaimTypes.NameIdentifier, result.Principal.GetClaim(ClaimTypes.NameIdentifier));
.SetClaim(ClaimTypes.NameIdentifier, result.Principal.GetClaim(ClaimTypes.NameIdentifier));
// Preserve the registration identifier to be able to resolve it later. // Preserve the registration identifier to be able to resolve it later.
identity.SetClaim(Claims.Private.RegistrationId, result.Principal.GetClaim(Claims.Private.RegistrationId)); identity.SetClaim(Claims.Private.RegistrationId, result.Principal.GetClaim(Claims.Private.RegistrationId));

17
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 the user principal can't be extracted or the cookie is too old.
// - If prompt=login was specified by the client application. // - 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. // - 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) || if (result == null || !result.Succeeded || request.HasPrompt(Prompts.Login) ||
(request.MaxAge != null && result.Properties?.IssuedUtc != null && (request.MaxAge != null && result.Properties?.IssuedUtc != null &&
DateTimeOffset.UtcNow - result.Properties.IssuedUtc > TimeSpan.FromSeconds(request.MaxAge.Value))) 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(properties, OpenIddictClientAspNetCoreDefaults.AuthenticationScheme);
} }
return Challenge( // For scenarios where the default challenge handler configured in the ASP.NET Core
authenticationSchemes: IdentityConstants.ApplicationScheme, // authentication options shouldn't be used, a specific scheme can be specified here.
properties: new AuthenticationProperties return Challenge(new AuthenticationProperties
{ {
RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters) RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters)
}); });
} }
// Retrieve the profile of the logged in user. // Retrieve the profile of the logged in user.

Loading…
Cancel
Save