Hi jwick,
thanks for the question.
All SFTP server events are synchronous now. We probably redesign events when we will have async SSH core.
When another library provides only async API, you have to use the "sync over async" call as the smallest evil. We are aware that "sync over async" call is far from ideal and may cause problems when your server is under heavy load (using more threads than necessary, thread pool starvation).
Please try the following code.
//Handle Authentication event to authenticate users against the database. Don't use await in the **async void** event handler, delegate to Task-based method and Wait for the result.
_sftpServer.Authentication += (sender, args) => SftpServerAuthentication(sender, args).Wait();
//Always use ConfigureAwait(false) in the 'await' expression.
/// <summary>
/// Handler for the <see cref="Server.Authentication"/> event.
/// </summary>
private static async Task SftpServerAuthentication(object sender, AuthenticationEventArgs e)
{
//Create 'anonymous' FileSystemDbContext for administrative task - user authentication.
using var context = new FileSystemDbContext(_options);
//Read user name from AuthenticationEventArgs.
var currentUserName = e.UserName;
//Load a user from database.
var user = await context.GetUserByName(currentUserName).ConfigureAwait(false);
//When a user is not in our database, deny access.
if (user == null)
{
e.Reject();
return;
}
//Verify user password
if (!_passwordHashService.VerifyPassword(user, e.Password))
{
//When user sends invalid password, deny access.
e.Reject();
return;
}
//Create "user session scoped" instance of the FileSystemDbContext.
var fileSystemDbContext = new FileSystemDbContext(_options, currentUserName);
//Create "user session scoped" instance of the EfFileSystemProvider.
var efFileSystemProvider = new EfFileSystemProvider(fileSystemDbContext);
//Create instance of our DbFileServerUser with user specific file system.
var dbFileServerUser = new DbFileServerUser(currentUserName, efFileSystemProvider);
//Authentication succeeded. Allow user logon.
e.Accept(dbFileServerUser);
}