Статьи

Как получить доступ к SMTP и IMAP-серверам с помощью OAuth внутри приложений .NET

Этот технический совет объясняет, как разработчики .NET могут получить доступ к SMTP и IMAP-серверу, используя OAuth внутри приложений .NET. Aspose.Email для .NET можно использовать для доступа к серверам SMTP и IMAP. Поддержка OAuth для почты Google реализована только для версии 2.0, поскольку OAuth 1.0 официально объявлен устаревшим с 20 апреля 2012 года. На данный момент Google поддерживает OAuth только для платформы Google Apps, и общедоступные почтовые учетные записи нельзя использовать с OAuth механизм. Когда создается новый аккаунт Google Apps, для этого аккаунта необходимо зарегистрировать новое «Установленное приложение» для тестирования в консоли API. Могут быть созданы бесплатные пробные аккаунты, предоставляемые Google Apps для бизнеса.

Примеры кода для доступа к серверам SMTP и IMAP с помощью Aspose.Email приведены ниже:

//[C# Code Sample]

static void Main(string[] args)
    {
        // The authorizationCode should be replaced with your value.
        // To get authorizationCode use the URL bellow:
        // https://accounts.google.com/o/oauth2/auth?redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&client_id=929645059575.apps.googleusercontent.com&scope=https%3A%2F%2Fmail.google.com%2F
        string authorizationCode = "4/zx4_I4ZhhUdmgLdsejpjeMkwAAMs.kk7o1Qx9U28VOl05ti8ZT3Y1uIlidQI";  // authorizationCode should be replaced with new value !!!!!!!
        string accessToken = GetAccessToken(authorizationCode);
        AccessSMTPServer(accessToken);
        AccessIMAPServer(accessToken);
    }

    static void AccessSMTPServer(string accessToken)
    {
        MailMessage message = new MailMessage(
            "user1@testaccount1913.narod2.ru",
            "user1@testaccount1913.narod2.ru",
            "NETWORKNET-33499 - " + Guid.NewGuid().ToString(),
            "Access to SMTP servers using OAuth");
        using (SmtpClient client = new SmtpClient("smtp.gmail.com", 587, "user1@testaccount1913.narod2.ru", accessToken, true))
        {
            client.Timeout = 400000;
            client.SecurityMode = SmtpSslSecurityMode.Implicit;
            client.EnableSsl = true;
            client.Send(message);
        }
    }


    static void AccessIMAPServer(string accessToken)
    {
        using (ImapClient client = new ImapClient("imap.gmail.com", 993, "user1@testaccount1913.narod2.ru", accessToken, true))
        {
            client.EnableSsl = true;
            client.SecurityMode = ImapSslSecurityMode.Implicit;
            client.Connect();
            client.SelectFolder("Inbox");
            ImapMessageInfoCollection messageInfoCol = client.ListMessages();
        }
    }

    internal static string GetAccessToken(string authorizationCode)
    {
        string actionUrl = "https://accounts.google.com/o/oauth2/token";
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(actionUrl);
        request.CookieContainer = new CookieContainer();
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        string encodedParameters = string.Format(
            "client_id={1}&code={0}&client_secret={2}&redirect_uri={3}&grant_type={4}",
            HttpUtility.UrlEncode(authorizationCode),
            HttpUtility.UrlEncode("929645059575.apps.googleusercontent.com"),
            HttpUtility.UrlEncode("USnH5eQRsC4XrjJbpGG7WVq5"),
            HttpUtility.UrlEncode("urn:ietf:wg:oauth:2.0:oob"),
            HttpUtility.UrlEncode("authorization_code")
            );
        byte[] requestData = Encoding.UTF8.GetBytes(encodedParameters);
        request.ContentLength = requestData.Length;
        if (requestData.Length > 0)
            using (Stream stream = request.GetRequestStream())
                stream.Write(requestData, 0, requestData.Length);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        string responseText = null;
        using (TextReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII))
            responseText = reader.ReadToEnd();
        string accessToken = null;
        foreach (string sPair in responseText.
            Replace("{", "").
            Replace("}", "").
            Replace("\"", "").
            Split(new string[] { ",\n" }, StringSplitOptions.None))
        {
            string[] pair = sPair.Split(':');
            if ("access_token" == pair[0].Trim())
            {
                accessToken = pair[1].Trim();
                break;
            }
        }
        return accessToken;
    }

//[VB.NET Code Sample]

Imports Aspose.Email.Mail
Imports System.Net
Imports Aspose.Email.Imap
Imports System.Text
Imports System.IO
Imports System.Web

Module Module1

    Sub Main()
        ' The authorizationCode should be replaced with your value.
        ' To get authorizationCode use the URL bellow:
        ' https://accounts.google.com/o/oauth2/auth?redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&client_id=929645059575.apps.googleusercontent.com&scope=https%3A%2F%2Fmail.google.com%2F
        Dim authorizationCode As String = "4/zx4_I4ZhhUdmgLdsejpjeMkwAAMs.kk7o1Qx9U28VOl05ti8ZT3Y1uIlidQI"
        ' authorizationCode should be replaced with new value !!!!!!!
        Dim accessToken As String = GetAccessToken(authorizationCode)
        AccessSMTPServer(accessToken)
        AccessIMAPServer(accessToken)

    End Sub
    Private Sub AccessSMTPServer(ByVal accessToken As String)
        Dim message As New MailMessage("user1@testaccount1913.narod2.ru", "user1@testaccount1913.narod2.ru", "NETWORKNET-33499 - " & Guid.NewGuid().ToString(), "Access to SMTP servers using OAuth")
        Using client As New SmtpClient("smtp.gmail.com", 587, "user1@testaccount1913.narod2.ru", accessToken, True)
            client.Timeout = 400000
            client.SecurityMode = SmtpSslSecurityMode.Implicit
            client.EnableSsl = True
            client.Send(message)
        End Using
    End Sub
    Private Sub AccessIMAPServer(ByVal accessToken As String)
        Using client As New ImapClient("imap.gmail.com", 993, "user1@testaccount1913.narod2.ru", accessToken, True)
            client.EnableSsl = True
            client.SecurityMode = ImapSslSecurityMode.Implicit
            client.Connect()
            client.SelectFolder("Inbox")
            Dim messageInfoCol As ImapMessageInfoCollection = client.ListMessages()
        End Using
    End Sub
    Friend Function GetAccessToken(ByVal authorizationCode As String) As String
        Dim actionUrl As String = "https://accounts.google.com/o/oauth2/token"
        Dim request As HttpWebRequest = DirectCast(WebRequest.Create(actionUrl), HttpWebRequest)
        request.CookieContainer = New CookieContainer()
        request.Method = "POST"
        request.ContentType = "application/x-www-form-urlencoded"
        Dim encodedParameters As String = String.Format("client_id={1}&code={0}&client_secret={2}&redirect_uri={3}&grant_type={4}", HttpUtility.UrlEncode(authorizationCode), HttpUtility.UrlEncode("929645059575.apps.googleusercontent.com"), HttpUtility.UrlEncode("USnH5eQRsC4XrjJbpGG7WVq5"), HttpUtility.UrlEncode("urn:ietf:wg:oauth:2.0:oob"), HttpUtility.UrlEncode("authorization_code"))
        Dim requestData As Byte() = Encoding.UTF8.GetBytes(encodedParameters)
        request.ContentLength = requestData.Length
        If requestData.Length > 0 Then
            Using stream As IO.Stream = request.GetRequestStream()
                stream.Write(requestData, 0, requestData.Length)
            End Using
        End If
        Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
        Dim responseText As String = Nothing
        Using reader As TextReader = New StreamReader(response.GetResponseStream(), Encoding.ASCII)
            responseText = reader.ReadToEnd()
        End Using
        Dim accessToken As String = Nothing
        For Each sPair As String In responseText.Replace("{", "").Replace("}", "").Replace("""", "").Split(New String() {"," & vbLf}, StringSplitOptions.None)
            Dim pair As String() = sPair.Split(":"c)
            If "access_token" = pair(0).Trim() Then
                accessToken = pair(1).Trim()
                Exit For
            End If
        Next
        Return accessToken
    End Function
End Module