PowerTCP Mail for .NET
OAuth Overview



OAuth

OAuth usage is implemented by obtaining an access token through the server's OAuth interface, and using that access token to log into the server, as demonstrated against our component below (the implementation is identical for SMTP/POP):

Imap Authentication with OAuth
Copy Code
/// <summary>
/// Connects to an Imap server, and authenticates the user using OAuth.
/// </summary>
/// <param name="myImap">The Imap instance to connect and authenticate</param>
/// <param name="hostNameOrAddress">The server's hostname or IP address.</param>
/// <param name="emailAddress">The user's email address.</param>
/// <param name="accessToken">An access token provided by the server's OAuth interface.</param>
public void AuthenticateWithOAuth(Imap myImap, string hostNameOrAddress, string emailAddress, string accessToken)
{
    //Set the method of encryption - Implicit/Explicit
    myImap.Session.Security.Encrypt = Encrypt.Implicit;

    //Optionally set the protocols available for SSL/TLS negotiation (defaults to SslProtocols.Default)
    //TLS 1.1/1.2 requires .NET 4.5+. See the SslProtocols MSDN documentation for more information.
    myImap.Session.Security.Protocols = SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;

    //Specify the server certificate validation callback
    myImap.Session.Security.ValidationCallback = remoteCertificateValidation;

    //Set the server address and port. If the server uses a non-standard port, it should be substituted here.
    //GetDefaultPort() returns the common port used for the security configuration.
    myImap.Session.RemoteEndPoint = new IPEndPoint(hostNameOrAddress, Imap.GetDefaultPort(myImap.Session));

    //Connect to the server.
    myImap.Connect();

    //Authenticate the user.
    //OAuth2 isn't used automatically by Authentication.Auto, so must be specified:
    myImap.Session.Authentication = Authentication.OAuth2;
    myImap.Session.Username = emailAddress;
    myImap.Session.Password = accessToken;
    myImap.Authenticate();
}

private bool remoteCertificateValidation(Object sender, X509Certificate remoteCertificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    //For this simple snippet, accept all server certificates. Please see the 'Security' top-level help topics, or 
    //the System.Net.Security.RemoteCertificateValidationCallback MSDN documentation, for more information.
    return true;
}
Imap Authentication with OAuth
Copy Code
''' <summary>
''' Connects to an Imap server, and authenticates the user using OAuth.
''' </summary>
''' <param name="myImap">The Imap instance to connect and authenticate</param>
''' <param name="hostNameOrAddress">The server's hostname or IP address.</param>
''' <param name="emailAddress">The user's email address.</param>
''' <param name="accessToken">An access token provided by the server's OAuth interface.</param>
Public Sub AuthenticateWithOAuth(ByVal myImap As Imap, ByVal hostNameOrAddress As String, ByVal emailAddress As String, ByVal accessToken As String)
    'Set the method of encryption - Implicit/Explicit
    myImap.Session.Security.Encrypt = Encrypt.Implicit

    'Optionally set the protocols available for SSL/TLS negotiation (defaults to SslProtocols.Default)
    'TLS 1.1/1.2 requires .NET 4.5+. See the SslProtocols MSDN documentation for more information.
    myImap.Session.Security.Protocols = SslProtocols.Ssl3 Or SslProtocols.Tls Or SslProtocols.Tls11 Or SslProtocols.Tls12

    'Specify the server certificate validation callback
    myImap.Session.Security.ValidationCallback = AddressOf remoteCertificateValidation

    'Set the server address and port. If the server uses a non-standard port, it should be substituted here.
    'GetDefaultPort() returns the common port used for the security configuration.
    myImap.Session.RemoteEndPoint = New IPEndPoint(hostNameOrAddress, Imap.GetDefaultPort(myImap.Session))

    'Connect to the server.
    myImap.Connect()

    'Authenticate the user.
    'OAuth2 isn't used automatically by Authentication.Auto, so must be specified:
    myImap.Session.Authentication = Authentication.OAuth2
    myImap.Session.Username = emailAddress
    myImap.Session.Password = accessToken
    myImap.Authenticate()
End Sub

Private Function remoteCertificateValidation(ByVal sender As Object, ByVal remoteCertificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
    'For this simple snippet, accept all server certificates. Please see the 'Security' top-level help topics, or 
    'the System.Net.Security.RemoteCertificateValidationCallback MSDN documentation, for more information.
    Return True
End Function

Obtaining an Access Token

Examine your server's documentation for current information on how to acquire an access token through their interface. Implementation will vary by server; we demonstrate against Gmail's API in this topic. See Google's documentation on how to acquire developer credentials (client_secret.json) and download the Gmail API here.

The snippet below demonstrates simple usage in an environment that a web browser can launch within (such as Windows Forms):

Obtain a Gmail Access Token
Copy Code
/// <summary>
/// Gets an OAuth access token for the user's Gmail account.
/// </summary>
/// <param name="emailAddress">The user's Gmail address/username</param>
/// <returns>An OAuth access token.</returns>
/// <remarks>
/// Launches a web browser for the user to verify the application's access to their account.
/// Targets Google.Apis.Gmail.v1 1.10.1.425. May not be compatible with later versions.
/// </remarks>
public async Task<string> GetGmailOAuthAccessTokenAsync(string emailAddress)
{
    UserCredential credential;
    //client_secrets.json - The Gmail developer credentials file. 
    //For more information see Google's documentation:
    //https://developers.google.com/gmail/api/quickstart/dotnet
    using (FileStream fs = File.OpenRead("client_secrets.json"))
    {
        credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
            GoogleClientSecrets.Load(fs).Secrets,
            new[] { GmailService.Scope.MailGoogleCom },
            emailAddress, CancellationToken.None);
    }
    return await credential.GetAccessTokenForRequestAsync(null, CancellationToken.None);
}
Obtain a Gmail Access Token
Copy Code
''' <summary>
''' Gets an OAuth access token for the user's Gmail account.
''' </summary>
''' <param name="emailAddress">The user's Gmail address/username</param>
''' <returns>An OAuth access token.</returns>
''' <remarks>
''' Launches a web browser for the user to verify the application's access to their account.
''' Targets Google.Apis.Gmail.v1 1.10.1.425. May not be compatible with later versions.
''' </remarks>
Public Async Function GetGmailOAuthAccessTokenAsync(ByVal emailAddress As String) As Task(Of String)
    Dim credential As UserCredential
    'client_secrets.json - The Gmail developer credentials file. 
    'For more information see Google's documentation:
    'https://developers.google.com/gmail/api/quickstart/dotnet
    Using fs As FileStream = File.OpenRead("client_secrets.json")
        credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(fs).Secrets, { GmailService.Scope.MailGoogleCom }, emailAddress, CancellationToken.None)
    End Using
    Return Await credential.GetAccessTokenForRequestAsync(Nothing, CancellationToken.None)
End Function

For other application types such as ASP.NET, see Google's documentation and snippets here, and the reference documentation for their UserCredential and ServiceAccountCredential classes linked within for information on the methods used to acquire the access token.


PowerTCP Mail for .NET Documentation Version 4.3
© 2018 Dart Communications. All Rights Reserved.
Send comments on this topic