SMTP authentication in detail


SMTP authentication explained

SMTP authentication allows the client to show the server that this client has permission to relay e-mail through this server.

In most cases, you can send without authentication to local e-mail addresses of this domain (i.e. send from bob@domain.com to alice@domain.com) because the server does not need to relay your e-mail to external servers. Authentication is required whenever the recipient is not of a local domain (i.e. send from joe@company.com to tom@example.com, provided that company.com and example.com use different e-mail servers).

Every rule has its exceptions. Some servers require the client to authenticate itself even when sending to a local domain. But more popular case is opposite - some servers do not support authentication but allow the client to send with no limitations (so called open relays). To avoid exploiting such server by spammers, it usually restricts the IP address list of allowed sender. Typical case if when your application resides on such server and the server allows unauthenticated servers to relay e-mail only if they connect from the server computer itself.

When authentication is enabled, you usually need to supply your login name and password on this server (although variants with other parameters exist as well, such as OAuth tokens). The login name is the most tricky part: it can be your account name, account@domaindomain\accountdomain\account\alias (in MS Exchange), and so on. For instance, if you're using account name in Outlook (which uses MAPI instead of SMTP), the SMTP name for the same could be domain\account.

There are two types of SMTP authentication, both supported by MailBee.NET:


POP-before-SMTP or ESMTP?

The only reason to use POP-before-SMTP authentication is the lack of support of ESMTP authentication by the server. However, if the server does not advertize ESMTP authentication support in response to EHLO command, it does not yet mean you have to use POP-before-SMTP.

Typical reasons why a newer server (which can support ESMTP authentication) might not advertize this capability to a client:

If any of the above is the case, it does not make sense to use POP-before-SMTP as it won't work anyway.


Authenticate with POP-before-SMTP

Generally speaking, POP-before-SMTP authentication is just an awkward way to overcome the limitation of the original SMTP protocol which did not support any authentication mechanism (ESMTP authentication has been invented years later). The idea is to connect to the POP3 service of the same e-mail server, authenticate there, and then immediately connect via SMTP to the same server. The server will remember your IP address for a few moments, and the SMTP part of the server will know that you recently passed POP3 authentication on this server.

Of course, this is not very secure (many different clients can have the same IP address due to NATs and proxies), and requires the server run both POP3 and SMTP services on the same system.

Anyway, if you have to use POP-before-SMTP, that's how you can do it:

Smtp mailer = new Smtp();

// See in the log file what exactly happens during POP-before-SMTP.
mailer.Log.Enabled = true;
mailer.Log.Filename = "C:\\Temp\\log.txt";
mailer.Log.Clear();

// Add SMTP relay, no ESMTP authentication.
mailer.SmtpServers.Add("smtp.domain.com");

// Authenticate with POP-before-SMTP.
mailer.AuthPopBeforeSmtp("pop.domain.com", 110, "jdoe", "secret");

// Compose and send an e-mail.
mailer.From.Email = "jdoe@domain.com";
mailer.To.Add("jane@example.com");
mailer.Subject = "Test message";
mailer.Send();
Dim mailer As New Smtp()

' See in the log file what exactly happens during POP-before-SMTP.
mailer.Log.Enabled = True
mailer.Log.Filename = "C:\Temp\log.txt"
mailer.Log.Clear()

' Add SMTP relay, no ESMTP authentication.
mailer.SmtpServers.Add("smtp.domain.com")

' Authenticate with POP-before-SMTP.
mailer.AuthPopBeforeSmtp("pop.domain.com", 110, "jdoe", "secret")

' Compose and send an e-mail.
mailer.From.Email = "jdoe@domain.com"
mailer.To.Add("jane@example.com")
mailer.Subject = "Test message"
mailer.Send()

Here and below, we assume MailBee and MailBee.SmtpMail namespaces are imported and the license key is set. See Import namespaces and set license key topic for details.


ESMTP authentication in more detail

ESMTP authentication itself is not a particular method or algorithm. It's rather a protocol (SASL over SMTP). There are lots of particular authentication method implementations, and the most popular are: LOGIN, PLAIN, CRAM-MD5, DIGEST-MD5, NTLM, GSSAPI, XOAUTH, XOAUTH2. MailBee.NET supports them all and also provides the mechanism to implement your own methods.

The server lists the supported authentication methods in AUTH lines of the reply to EHLO command. All authentication data is base64-encoded to avoid issues with special symbols which may appear in username and password strings.

All methods except of LOGIN and PLAIN are secure and use hash-based algorithms. If LOGIN or PLAIN is being used, SSL connection is recommended if security considerations apply for your case (and many servers simply do not allow you to use these methods unless the connection is SSL-encrypted).

NTLM and GSSAPI methods are widely used by Microsoft products like MS Exchange or IIS SMTP Service.

SPA (Secure Password Authentication) is another name for NTLM.

NTLM and GSSAPI are often used in so-called Integrated Windows Authentication mode when the sender automatically uses the login and password of the Windows user under whose context the application runs. The application does not need to know the password of the user in order to operate their e-mail account. See Use Integrated Windows Authentication (no username and password required) topic for details.

Integrated Windows Authentication, however, won't work with a web application unless it's executed under the context of an interactive user. Most web apps are executed under a system user's account, not an interactive user's account.

The e-mail account password is also not required by the application in case of XOAUTH or XOAUTH2 method. It implements OAuth technology which lets applications access restricted resources via authorization instead of authentication. See Use OAuth 2.0 with Gmail, Outlook.com, Live.com or Hotmail.com topic for details.

MailBee.NET can automatically select the best (the most secure) authentication method supported by the given server, and this is the default behaviour. However, some servers do not properly support secure authentication methods, and it may be required to fallback to simpler methods. By default, MailBee.NET then tries an insecure method if the secure method fails. If you can't afford using insecure methods for security reasons, you can set AuthenticationOptions.DisableSimpleMethodAfterSecure flag.

More specifically, the server may require you to pass different login name for different authentication methods. For instance, a simpler method may accept just an account name while a secure method may also require you to supply your domain name, workstation name, etc. See Fine-tune SMTP authentication process topic for more details on how to apply various AuthenticationOptions flags.


Secure authentication

By default, if the server supports secure authentication, MailBee.NET will use it automatically. No further action is required on your part.

However, if the server does not support any secure methods, MailBee.NET by default downgrades to insecure methods if supported by the server. If you cannot allow this for security reasons, you can explicitly specify which authentication methods to use. The sample below will connect to the e-mail server only if it supports secure authentication:

Smtp mailer = new Smtp();

// See in the log file what exactly happens during authentication.
mailer.Log.Enabled = true;
mailer.Log.Filename = "C:\\Temp\\log.txt";
mailer.Log.Clear();

// Use SMTP relay with authentication (username in MS Exchange style).
SmtpServer relay = mailer.SmtpServers.Add(
    "smtp.here.com", "jdoe\\here.com", "secret");

// Allow secure authentication methods only.
relay.AuthMethods = AuthenticationMethods.SaslCramMD5 |
    AuthenticationMethods.SaslDigestMD5 |
    AuthenticationMethods.SaslGssApi |
    AuthenticationMethods.SaslNtlm;

// Compose and send an e-mail.
mailer.From.Email = "jdoe@here.com";
mailer.To.Add("jane@example.com");
mailer.Subject = "Test message";
mailer.Send();
Dim mailer As New Smtp()

' See in the log file what exactly happens during authentication.
mailer.Log.Enabled = True
mailer.Log.Filename = "C:\Temp\log.txt"
mailer.Log.Clear()

' Use SMTP relay with authentication (username in MS Exchange style).
Dim relay As SmtpServer = mailer.SmtpServers.Add( _
    "smtp.here.com", "jdoe\here.com", "secret")

' Allow secure authentication methods only.
relay.AuthMethods = AuthenticationMethods.SaslCramMD5 Or _
    AuthenticationMethods.SaslDigestMD5 Or _
    AuthenticationMethods.SaslGssApi Or _
    AuthenticationMethods.SaslNtlm

' Compose and send an e-mail.
mailer.From.Email = "jdoe@here.com"
mailer.To.Add("jane@example.com")
mailer.Subject = "Test message"
mailer.Send()

If the server does not support any secure methods, MailBee.NET will throw MailBeeLoginNoSupportedMethodsException.

Note that we haven't included OAuth in the list of the allowed secure methods. OAuth, being the method of an authorization rather than authentication, is always used on its own because its parameters are not compatible with "real" authentication methods. MailBee.NET won't use OAuth unless it's the only method in the list of the allowed methods.


Use Integrated Windows Authentication (no username and password required)

NTLM and GSSAPI authentication methods can work in two modes:

IWA, however, cannot be used when the currently logged Windows user is not an interactive user. In web applications, you often deal with system users (like NETWORK SERVICE, ASPNET, etc). To be able to use IWA with MailBee.NET in an ASP.NET application, the application itself must run under the context of an interactive user (<authentication mode="Windows"/> in web.config).

Also, the user from whose context the authentication token is constructed, must have a valid mailbox on the e-mail server. This is an important note: even if the given user is registered in the Active Directory and can log in the domain, this does not necessarily mean that the system has already provisioned their mailbox.

Let's assume that the current user context denotes a user which has a mailbox on the e-mail server integrated with your Active Directory. The sample below authenticates using IWA and sends an e-mail:

Smtp mailer = new Smtp();

// See in the log file what exactly happens during authentication.
mailer.Log.Enabled = true;
mailer.Log.Filename = "C:\\Temp\\log.txt";
mailer.Log.Clear();

// Use SMTP relay with authentication (take credentials from Windows).
SmtpServer relay = mailer.SmtpServers.Add(
    "mail.domain.com", null, null);

// Allow methods which can do Integrated Windows Authentication.
relay.AuthMethods = AuthenticationMethods.SaslNtlm |
    AuthenticationMethods.SaslGssApi;

// Compose and send an e-mail.
mailer.From.Email = "jdoe@domain.com";
mailer.To.Add("jane@example.com");
mailer.Subject = "Test message";
mailer.Send();
Dim mailer As New Smtp()

' See in the log file what exactly happens during authentication.
mailer.Log.Enabled = True
mailer.Log.Filename = "C:\Temp\log.txt"
mailer.Log.Clear()

' Use SMTP relay with authentication (take credentials from Windows).
Dim relay As SmtpServer = mailer.SmtpServers.Add( _
    "mail.domain.com", CType(Nothing, String), CType(Nothing, String))

' Allow methods which can do Integrated Windows Authentication.
relay.AuthMethods = AuthenticationMethods.SaslNtlm Or _
    AuthenticationMethods.SaslGssApi

' Compose and send an e-mail.
mailer.From.Email = "jdoe@domain.com"
mailer.To.Add("jane@example.com")
mailer.Subject = "Test message"
mailer.Send()

Use OAuth 2.0 with Gmail, Outlook.com, Live.com or Hotmail.com

OAuth addresses the common problem when the user does not want to give their password away to the external system which needs access to their data.

MailBee.NET provides the detailed tutorial and samples covering many aspects of OAuth 2.0 usage with Google and Microsoft providers. You can find it at OAuth 2.0 in Windows and ASP.NET MVC apps page.


Fine-tune SMTP authentication process

MailBee.NET supports lots of parameters and options that affect the authentication process. The most important are:

The code snippet below makes MailBee.NET to use an insecure method even if a secure method seems to be supported. MailBee.NET will still use a secure method when no insecure methods are supported by the server:

SmtpServer relay = mailer.SmtpServers.Add(
    "smtp.here.com""joe""secret");

relay.AuthOptions = AuthenticationOptions.PreferSimpleMethods;
Dim relay As SmtpServer = mailer.SmtpServers.Add( _
    "smtp.here.com""joe""secret")

relay.AuthOptions = AuthenticationOptions.PreferSimpleMethods

We assume mailer is an Smtp instance.

The next code snippet configures MailBee.NET to use GSSAPI/Kerberos authentication when using SMTP Service of Microsoft IIS 7 or higher:

SmtpServer relay = mailer.SmtpServers.Add(
    "mail.company.com""joe""secret");

relay.AccountDomain = "company.com";
relay.TargetName = "SmtpSvc/mail.company.com";
relay.AuthMethods = AuthenticationMethods.SaslGssApi;
Dim relay As SmtpServer = mailer.SmtpServers.Add( _
    "mail.company.com""joe""secret")

relay.AccountDomain = "company.com"
relay.TargetName = "SmtpSvc/mail.company.com"
relay.AuthMethods = AuthenticationMethods.SaslGssApi

You can explore AuthenticationOptions enumeration to learn which other options are available.


Create your own authentication method

To learn how create your own SASL method, refer to SaslMethod class documentation. It demonstrates creating a SASL method which is then used with Pop3 class but SASL methods are protocol-independent, so that you can use the same class you developed, with all protocols including SMTP.

The code snippet below indicates how to configure SmtpServer object so that MailBee.NET could use your custom method during the authentication process:

SmtpServer relay = mailer.SmtpServers.Add(
    "mail.company.com""joe@domain.com""secret");

relay.AuthMethods = AuthenticationMethods.SaslUserDefined;
relay.AuthUserDefined = new SaslLoginMethod();
Dim relay As SmtpServer = mailer.SmtpServers.Add( _
    "mail.company.com""joe@domain.com""secret")

relay.AuthMethods = AuthenticationMethods.SaslUserDefined
relay.AuthUserDefined = New SaslLoginMethod()

We assume mailer is an Smtp instance and SaslLoginMethod represents your custom authentication method as defined in SaslMethod class documentation.

You can also use your custom method together with the standard methods. For instance, you can leave relay.AuthMethods in its default AuthenticationMethods.Auto state. MailBee.NET will treat your custom method accordingly the same rules applied to other methods (i.e. try it first if it's secure, do not try if the server does not advertize this method as supported, etc).


Send feedback to AfterLogic

Copyright © 2006-2017 AfterLogic Corporation. All rights reserved.