/// <summary> /// Private and generic tokenrequest. The function overloads has been split iot keep one generic token exchange method. /// </summary> /// <param name="request">TokenRequest</param> /// <param name="grantType">Specified method of login.</param> /// <returns>A valid json web token.</returns> public async Task <TokenResult> TokenExchange(TokenRequest request, GrantType grantType) { User user = null; switch (grantType) { case GrantType.Tenant: if (string.IsNullOrWhiteSpace(request.TenantKey)) { return(new TokenResult(400, "This tenantkey is unkown.")); } user = (await _userService.FindByTenantKeyAsync(request.TenantKey))?.Entity; if (user == null) { return(new TokenResult(400, "This tenantkey is unkown.")); } break; case GrantType.Password: if (string.IsNullOrEmpty(request.Email) || string.IsNullOrEmpty(request.Password)) { return(new TokenResult(400, "The username and/or password are required.")); } // be sure to check that the username is the email address // or rewrite the service functionality to also find by username user = await _userManager.FindByEmailAsync(_cryptoProvider.EncryptPrivate(request.Email)); if (user == null) { user = await _userManager.FindByNameAsync(request.Email); if (user == null) { return(new TokenResult(400, "The username/password couple is invalid.")); } } if (!await _userManager.CheckPasswordAsync(user, request.Password)) { return(new TokenResult(400, "The username/password couple is invalid.")); } break; } // when no user is found, then terminate the request. if (user == null) { return(new TokenResult(400, "The specified grant type is not supported.")); } if (!await _userManager.IsEmailConfirmedAsync(user)) { return(new TokenResult(401, "Please confirm your email or reset your password.")); } if (user.BlockedUntilUtc.HasValue && user.BlockedUntilUtc.Value > DateTime.UtcNow) { return(new TokenResult(401, MessageHelper.BlockedUntilMessage(user.BlockedUntilUtc))); } if (await _userManager.IsLockedOutAsync(user)) { return(new TokenResult(401, "The account is locked out.")); } if (!await _signInManager.CanSignInAsync(user)) { return(new TokenResult(401, "The specified user is not allowed to sign in.")); } // reset locks await _userManager.ResetAccessFailedCountAsync(user); await _userManager.SetLockoutEnabledAsync(user, false); // Create a new authentication token. var token = await GetJwtSecurityToken(user, grantType); return(new TokenResult(200) { TokenData = new TokenData { Token = new JwtSecurityTokenHandler().WriteToken(token), ExpiredDateUtc = token.ValidTo } }); }