ApacheMinaSSHD.NET supports multiple authentication methods, including multi-factor authentication (MFA) via authentication method groups. All authenticators are deny-by-default — no user is allowed unless explicitly configured.
server.SetFixedPasswordAuthenticator("username", "password");Uses constant-time comparison (CryptographicOperations.FixedTimeEquals) to prevent timing attacks.
server.SetDelegatePasswordAuthenticator(
(username, password, session) =>
{
// Validate against your identity store
return ValidateUser(username, password);
});The callback receives ISshSession with RemoteAddress and SessionId for audit context.
class MyPasswordAuth : IAMNetPasswordAuthenticator
{
public bool Authenticate(string username, string password, ISshSession session)
{
// Your identity store logic here
return Database.ValidateCredentials(username, password);
}
// Optional: support password change
public bool HandlePasswordChangeRequest(string username, string oldPassword, string newPassword, ISshSession session)
{
return Database.ChangePassword(username, oldPassword, newPassword);
}
}
server.SetPasswordAuthenticator(new MyPasswordAuth());server.SetCompositePasswordAuthenticator(
new LdapPasswordAuthenticator(),
new LocalPasswordAuthenticator(),
new AMNetFixedPasswordAuthenticator("admin", "emergency-pass"));Each authenticator is tried in order until one accepts the credentials.
server.SetFingerprintPublickeyAuthenticator("username",
"SHA256:abc123...",
"SHA256:def456...");OpenSSH-compatible authorized_keys file:
server.SetAuthorizedKeysAuthenticator("/path/to/authorized_keys");server.SetDelegatePublickeyAuthenticator(
(username, fingerprint, session) =>
{
return Database.KeyIsAllowed(username, fingerprint);
});class MyPublicKeyAuth : IAMNetPublickeyAuthenticator
{
public bool Authenticate(string username, string fingerprint, ISshSession session)
{
return ValidatePublicKey(username, fingerprint);
}
}
server.SetPublickeyAuthenticator(new MyPublicKeyAuth());server.SetCompositePublickeyAuthenticator(
new DatabaseKeyAuth(),
new FileBasedKeyAuth());The AMNetPublickeyAuthenticator scans an Authorized_Keys directory for files matching the username. Supports PEM, OpenSSH public key, OpenSSH private key, and SSH2 public key formats.
server.SetPublickeyAuthenticator(new AMNetPublickeyAuthenticator(basePath));server.SetFixedKeyboardInteractiveAuthenticator(
expectedResponse: "123456",
username: "user",
prompt: "Verification code",
interactionName: "2FA",
instruction: "Enter the code from your authenticator app.");server.SetDelegateKeyboardInteractiveAuthenticator(
generateChallenge: (username, challenge) =>
{
challenge.AddPrompt("Current PIN:", false);
challenge.AddPrompt("New PIN:", true);
},
authenticate: (session, username, responses) =>
{
return responses.GetResponses()[0] == "1234" && responses.GetResponses()[1] == "5678";
});Require multiple authentication methods to succeed sequentially:
// Require public key first, then password
server.SetAuthenticationMethods(
AMNetSshAuthenticationMethods.PublicKey,
AMNetSshAuthenticationMethods.Password);Or require multiple methods in one step:
// Require both password AND keyboard-interactive (in sequence)
server.SetAuthenticationMethods(
AMNetSshAuthenticationMethods.RequireAll(
AMNetSshAuthenticationMethods.Password,
AMNetSshAuthenticationMethods.KeyboardInteractive));Or offer alternative combinations:
// Either public key alone, OR password+keyboard-interactive
server.SetAuthenticationMethodGroups(
new[] { AMNetSshAuthenticationMethods.PublicKey },
new[] {
AMNetSshAuthenticationMethods.Password,
AMNetSshAuthenticationMethods.KeyboardInteractive
});Host-based authentication verifies a client by the host key and hostname from which the connection originates, in addition to the username.
server.SetDelegateHostBasedAuthenticator(
(username, fingerprint, clientHostname, clientUsername, session) =>
{
// Validate the host key fingerprint and client hostname
return AllowedHosts.ContainsKey(clientHostname) &&
AllowedHosts[clientHostname] == fingerprint;
});The callback receives:
username— The SSH username being authenticatedfingerprint— SHA-256 fingerprint of the client's host keyclientHostname— The hostname claimed by the clientclientUsername— The username on the client machinesession— Session metadata for audit context
class MyHostBasedAuth : IAMNetHostBasedAuthenticator
{
public bool Authenticate(string username, string fingerprint,
string clientHostname, string clientUsername, ISshSession session)
{
return HostDatabase.IsTrustedHost(clientHostname, fingerprint);
}
}
server.SetHostBasedAuthenticator(new MyHostBasedAuth());Host-based authentication is typically combined with public key or password as a multi-factor method. Add it to an authentication chain:
server.SetAuthenticationMethods(
AMNetSshAuthenticationMethods.PublicKey,
AMNetSshAuthenticationMethods.HostBased);GSSAPI (Generic Security Services API) enables Kerberos-based single sign-on authentication for SSH connections.
server.SetDelegateGssapiAuthenticator(
(session, identity) =>
{
// identity is the Kerberos principal (e.g., user@REALM)
return KerberosService.ValidatePrincipal(identity);
});class MyGssapiAuth : IAMNetGssapiAuthenticator
{
public bool ValidateIdentity(ISshSession session, string identity)
{
// Validate the Kerberos principal
return identity.EndsWith("@YOUR-REALM.COM");
}
}
server.SetGssapiAuthenticator(new MyGssapiAuth());GSSAPI is typically used alongside other methods:
server.SetAuthenticationMethods(
AMNetSshAuthenticationMethods.Gssapi);Monitor authentication and session lifecycle:
server.addSessionListener(new AMNetSessionListener());Low-level connection monitoring:
server.setIoServiceEventListener(new AMNetIoServiceEventListener());PROXY protocol support for load balancers:
server.setServerProxyAcceptor(new AMNetServerProxyAcceptor());| Issue | Cause | Fix |
|---|---|---|
| All logins rejected | Authenticator deny-by-default | Configure at least one authenticator with SetPasswordAuthenticator() or equivalent |
| Public key auth fails | Wrong key format | Use OpenSSH format (ssh-rsa AAA...), not -----BEGIN RSA PRIVATE KEY----- |
| MFA stops working mid-session | Auth method order matters | Configure methods before starting the server |
| Delegate authenticator not called | Wrong method used | Use SetDelegatePasswordAuthenticator(), not SetPasswordAuthenticator() with a custom class |
See AuthenticationServer for runnable examples of every auth mode.
Next: Virtual Filesystem — root jail isolation, user home directories, and path containment.
ApacheMinaSSHD.NET is maintained by SERALYNX LLC. For a turnkey portable SFTP server with enterprise authentication, monitoring, and GUI management, visit Porta SFTP Server.