public override async Task HandleTokenRequest(HandleTokenRequestContext context) { // Resolve ASP.NET Core Identity's user manager from the DI container. var manager = context.HttpContext.RequestServices.GetRequiredService<UserManager<ApplicationUser>>(); // Only handle grant_type=password requests and let ASOS // process grant_type=refresh_token requests automatically. if (context.Request.IsPasswordGrantType()) { var user = await manager.FindByNameAsync(context.Request.Username); if (user == null) { context.Reject( error: OpenIdConnectConstants.Errors.InvalidGrant, description: "Invalid credentials."); return; } // Ensure the user is not already locked out. if (manager.SupportsUserLockout && await manager.IsLockedOutAsync(user)) { context.Reject( error: OpenIdConnectConstants.Errors.InvalidGrant, description: "Invalid credentials."); return; } // Ensure the password is valid. if (!await manager.CheckPasswordAsync(user, context.Request.Password)) { if (manager.SupportsUserLockout) { await manager.AccessFailedAsync(user); } context.Reject( error: OpenIdConnectConstants.Errors.InvalidGrant, description: "Invalid credentials."); return; } if (manager.SupportsUserLockout) { await manager.ResetAccessFailedCountAsync(user); } // Reject the token request if two-factor authentication has been enabled by the user. if (manager.SupportsUserTwoFactor && await manager.GetTwoFactorEnabledAsync(user)) { context.Reject( error: OpenIdConnectConstants.Errors.InvalidGrant, description: "Two-factor authentication is required for this account."); return; } var identity = new ClaimsIdentity(context.Options.AuthenticationScheme); // Note: the name identifier is always included in both identity and // access tokens, even if an explicit destination is not specified. identity.AddClaim(ClaimTypes.NameIdentifier, await manager.GetUserIdAsync(user)); // When adding custom claims, you MUST specify one or more destinations. // Read "part 7" for more information about custom claims and scopes. identity.AddClaim("username", await manager.GetUserNameAsync(user), OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken); identity.AddClaim("firstName", user.FirstName, OpenIdConnectConstants.Destinations.IdentityToken); //Add roles var roles = await manager.GetRolesAsync(user); var roleClaims = new List<Claim>(); foreach(var role in roles) { identity.AddClaim(ClaimTypes.Role, role, OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken); } var estheticians = (IEstheticianService)context.HttpContext.RequestServices.GetService(typeof(IEstheticianService)); var esthetician = await estheticians.GetByEmailAsync(user.Email); if (esthetician != null) { identity.AddClaim("estheticianId", esthetician.Id.ToString(), OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken); } // Create a new authentication ticket holding the user identity. var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), context.Options.AuthenticationScheme); // Set the list of scopes granted to the client application. ticket.SetScopes( /* openid: */ OpenIdConnectConstants.Scopes.OpenId, /* email: */ OpenIdConnectConstants.Scopes.Email, /* profile: */ OpenIdConnectConstants.Scopes.Profile, /* offline_access */ OpenIdConnectConstants.Scopes.OfflineAccess); // Set the resource servers the access token should be issued for. ticket.SetResources("resource_server"); context.Validate(ticket); } }
public async Task<IActionResult> Accept(CancellationToken cancellationToken) { var response = HttpContext.GetOpenIdConnectResponse(); if (response != null) { return View("Error", response); } var request = HttpContext.GetOpenIdConnectRequest(); if (request == null) { return View("Error", new OpenIdConnectMessage { Error = OpenIdConnectConstants.Errors.ServerError, ErrorDescription = "An internal error has occurred" }); } // Create a new ClaimsIdentity containing the claims that // will be used to create an id_token, a token or a code. var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); // Copy the claims retrieved from the external identity provider // (e.g Google, Facebook, a WS-Fed provider or another OIDC server). foreach (var claim in HttpContext.User.Claims) { // Allow ClaimTypes.Name to be added in the id_token. // ClaimTypes.NameIdentifier is automatically added, even if its // destination is not defined or doesn't include "id_token". // The other claims won't be visible for the client application. if (claim.Type == ClaimTypes.Name) { claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken); } identity.AddClaim(claim); } var application = await GetApplicationAsync(request.ClientId, cancellationToken); if (application == null) { return View("Error", new OpenIdConnectMessage { Error = OpenIdConnectConstants.Errors.InvalidClient, ErrorDescription = "Details concerning the calling client application cannot be found in the database" }); } // Create a new ClaimsIdentity containing the claims associated with the application. // Note: setting identity.Actor is not mandatory but can be useful to access // the whole delegation chain from the resource server (see ResourceController.cs). identity.Actor = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.Actor.AddClaim(ClaimTypes.NameIdentifier, application.ApplicationID); identity.Actor.AddClaim(ClaimTypes.Name, application.DisplayName, OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken); // Create a new authentication ticket holding the user identity. var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), OpenIdConnectServerDefaults.AuthenticationScheme); // Set the list of scopes granted to the client application. // Note: this sample always grants the "openid", "email" and "profile" scopes // when they are requested by the client application: a real world application // would probably display a form allowing to select the scopes to grant. ticket.SetScopes(new[] { /* openid: */ OpenIdConnectConstants.Scopes.OpenId, /* email: */ OpenIdConnectConstants.Scopes.Email, /* profile: */ OpenIdConnectConstants.Scopes.Profile, /* offline_access: */ OpenIdConnectConstants.Scopes.OfflineAccess }.Intersect(request.GetScopes())); // Set the resources servers the access token should be issued for. ticket.SetResources("resource_server"); // Returning a SignInResult will ask ASOS to serialize the specified identity to build appropriate tokens. // Note: you should always make sure the identities you return contain ClaimTypes.NameIdentifier claim. // In this sample, the identity always contains the name identifier returned by the external provider. return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme); }
private AuthenticationProperties CreateAuthenticationProperties(ClaimsPrincipal principal) { var ticket = new AuthenticationTicket(principal, null, OpenIdConnectServerDefaults.AuthenticationScheme); ticket.SetResources(_configuration.WebHostName()); ticket.SetScopes(OpenIdConnectConstants.Scopes.OpenId, OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile, OpenIdConnectConstants.Scopes.OfflineAccess); return ticket.Properties; }