public async Task <IActionResult> Exchange() { var request = HttpContext.GetOpenIddictServerRequest() ?? throw new InvalidOperationException("The OpenID Connect request cannot be retrieved."); if (request.IsPasswordGrantType()) { var user = await _userManager.FindByNameAsync(request.Username); if (user is null) { return(Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The username/password couple is invalid." }))); } // Validate the username/password parameters and ensure the account is not locked out. var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password, lockoutOnFailure : true); if (!result.Succeeded) { return(Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The username/password couple is invalid." }))); } var principal = await _signInManager.CreateUserPrincipalAsync(user); // Note: in this sample, the granted scopes match the requested scope // but you may want to allow the user to uncheck specific scopes. // For that, simply restrict the list of scopes before calling SetScopes. principal.SetScopes(request.GetScopes()); principal.SetResources(await _scopeManager.ListResourcesAsync(principal.GetScopes()).ToListAsync()); foreach (var claim in principal.Claims) { claim.SetDestinations(GetDestinations(claim, principal)); } // Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens. return(SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } else if (request.IsAuthorizationCodeGrantType() || request.IsDeviceCodeGrantType() || request.IsRefreshTokenGrantType()) { // Retrieve the claims principal stored in the authorization code/device code/refresh token. var principal = (await HttpContext.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)) .Principal; // Retrieve the user profile corresponding to the authorization code/refresh token. // Note: if you want to automatically invalidate the authorization code/refresh token // when the user password/roles change, use the following line instead: // var user = _signInManager.ValidateSecurityStampAsync(info.Principal); var user = await _userManager.GetUserAsync(principal); if (user is null) { return(Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The token is no longer valid." }))); } // Ensure the user is still allowed to sign in. if (!await _signInManager.CanSignInAsync(user)) { return(Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties(new Dictionary <string, string> { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is no longer allowed to sign in." }))); } foreach (var claim in principal.Claims) { claim.SetDestinations(GetDestinations(claim, principal)); } // Returning a SignInResult will ask OpenIddict to issue the appropriate access/identity tokens. return(SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } else if (request.IsClientCredentialsGrantType()) { // Note: the client credentials are automatically validated by OpenIddict: // if client_id or client_secret are invalid, this action won't be invoked. var application = await _applicationManager.FindByClientIdAsync(request.ClientId); if (application == null) { throw new InvalidOperationException("The application details cannot be found in the database."); } // 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( TokenValidationParameters.DefaultAuthenticationType, Claims.Name, Claims.Role); // Use the client_id as the subject identifier. identity.AddClaim(Claims.Subject, await _applicationManager.GetClientIdAsync(application), Destinations.AccessToken, Destinations.IdentityToken); identity.AddClaim(Claims.Name, await _applicationManager.GetDisplayNameAsync(application), Destinations.AccessToken, Destinations.IdentityToken); var principal = new ClaimsPrincipal(); principal.AddIdentity(identity); // Note: in this sample, the granted scopes match the requested scope // but you may want to allow the user to uncheck specific scopes. // For that, simply restrict the list of scopes before calling SetScopes. principal.SetScopes(request.GetScopes()); principal.SetResources(await _scopeManager.ListResourcesAsync(principal.GetScopes()).ToListAsync()); foreach (var claim in principal.Claims) { claim.SetDestinations(GetDestinations(claim, principal)); } return(SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)); } throw new InvalidOperationException("The specified grant type is not supported."); }