public async Task <IActionResult> Login([FromBody] LoginRequest request) { var context = await _identity.GetAuthorizationContextAsync(request.ReturnUrl); if (context == null) { _logger.LogWarning("Cannot create authorization context. Return URL: {0}", request.ReturnUrl); return(Unauthorized()); } var tenant = context.Tenant ?? Constants.DefaultTenant; var user = await _userManager.FindByNameAndTenantAsync(request.Username, tenant); if (user == null) { _logger.LogWarning("User {0} not found in tenant {1}", request.Username, tenant); return(Unauthorized()); } var passwordCheck = await _signInManager.CheckPasswordSignInAsync(user, request.Password, false); if (!passwordCheck.Succeeded) { _logger.LogWarning("Incorrect password for user {0} in tenant {1}", request.Username, tenant); return(Unauthorized()); } var securityKeyVerification = await HttpContext.AuthenticateAsync(Constants.KeyAuthScheme); if (!securityKeyVerification.Succeeded) { _logger.LogInformation("No valid security key verification cookie found, requesting key sign in."); var keys = user.IsClinicAdmin ? await _keyManager.GetTenantAdminKeysAsync(tenant) : await _keyManager.GetTenantDeviceKeysAsync(tenant); if (keys.Count == 0) { _logger.LogWarning("No {0} authentication keys found for tenant {1}", user.IsClinicAdmin ? "admin" : "device", tenant); return(Unauthorized()); } var identity = new ClaimsIdentity(Constants.KeyAuthUserIdScheme); identity.AddClaim(new Claim(ClaimTypes.Name, user.Id)); identity.AddClaim(new Claim(ClaimTypes.UserData, request.ReturnUrl)); await HttpContext.SignInAsync(Constants.KeyAuthUserIdScheme, new ClaimsPrincipal(identity)); return(Ok(new { Keys = keys.Select(k => k.Id) })); } var result = await _signInManager.PasswordSignInAsync(user, request.Password, false, false); if (!result.Succeeded) { _logger.LogWarning("Failed to sign in user {0} to tenant {1}", request.Username, tenant); return(Unauthorized()); } return(Ok(new { request.ReturnUrl })); }