首页 > 解决方案 > 使用 oAuth2 重新连接 ews 流连接

问题描述

我正在重写我的后端服务,该服务使用 EWS 流连接监控邮箱,我正在将其从基本身份验证更改为 oAuth2。

一切正常,在服务启动时我订阅了邮箱,它创建了一个交换服务,检索一个身份验证令牌,然后监视邮箱 30 分钟,直到流连接到期。我有一个事件处理程序附加到订阅的 OnDisconnect 事件以自动重新连接。这也有效。但是,oAuth2 令牌的生命周期为 1 小时。所以第二次流连接尝试重新连接它失败并出现未经授权的错误代码。

当流连接超时时,如何强制它更新 oAuth 令牌并每 30 分钟重新连接一次使用更新的令牌?

这是我的代码:

获取身份验证令牌:

    Public Async Function getTokenAsync() As Task(Of String)

    Try
        Dim authority As String = ConfigurationManager.AppSettings("AuthorizationUri").Replace("common", "xxxxxxxxxxxxxxx")
        Dim authenticationContext As Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext = New Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(authority, False)
        Dim certfile As String = "D:\DevRepos\Test apps\oAuth2 EWS test app\testCert.pfx"
        Dim cert As X509Certificate2 = New X509Certificate2(certfile, "xxxx", X509KeyStorageFlags.MachineKeySet)
        Dim cac As Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate = New Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate("xxxxxxxxxxxx", cert)
        Dim authenticationResult = Await authenticationContext.AcquireTokenAsync("https://outlook.office365.com", cac)

        Return authenticationResult.AccessToken

    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try


    Return Nothing

End Function

创建交换服务:

    Public Async Function exchangeServiceconnection() As Task(Of ExchangeService)
    Dim test As Task(Of String)
    test = getTokenAsync()
    Dim result2 As String = Await test
    Dim ewsClient = New ExchangeService()

    Try
        ewsClient.Url = New Uri("https://outlook.office365.com/EWS/Exchange.asmx")
        ewsClient.Credentials = New OAuthCredentials(result2)
        ewsClient.ImpersonatedUserId = New ImpersonatedUserId(ConnectingIdType.SmtpAddress, "mailbox@testdomain.com")
        ewsClient.HttpHeaders.Add("X-AnchorMailbox", "mailbox@testdomain.com")

    Catch ex As MsalException
        MsgBox($"Error acquiring access token: {ex.ToString()}")
    Catch ex As Exception
        MsgBox($"Error: {ex.ToString()}")
    End Try

    Return ewsClient

End Function

订阅邮箱:

    Async Sub Subscribe()
    Dim service As ExchangeService
    service = Await exchangeServiceconnection()
    Dim locateMailbox = New Mailbox With {
        .Address = "mailbox@testdomain.com"
    }
    Dim folderId = New FolderId(WellKnownFolderName.Inbox, locateMailbox)
    Dim foldersToWatch = {folderId}
    Dim streamingSubscription As StreamingSubscription = service.SubscribeToStreamingNotifications(foldersToWatch, EventType.NewMail)
    Dim streamingConnection = New StreamingSubscriptionConnection(service, 30)
    streamingConnection.AddSubscription(streamingSubscription)
    AddHandler streamingConnection.OnSubscriptionError, AddressOf ResolveError
    AddHandler streamingConnection.OnDisconnect, AddressOf Reconnect
    AddHandler streamingConnection.OnNotificationEvent, AddressOf Form1.message
    streamingConnection.Open()
End Sub

重新连接处理程序:

    Public Sub Reconnect(ByVal sender As Object, ByVal disconnectEventArgs As SubscriptionErrorEventArgs)
    If Not CType(sender, StreamingSubscriptionConnection).IsOpen Then
        CType(sender, StreamingSubscriptionConnection).Open()
    End If
End Sub

错误重新连接:

    Public Sub ResolveError(ByVal sender As Object, ByVal errorEventArgs As SubscriptionErrorEventArgs)
    Dim streamingSubscriptionConnection = CType(sender, StreamingSubscriptionConnection)
    If Not streamingSubscriptionConnection.IsOpen Then streamingSubscriptionConnection.Open()
End Sub

标签: vb.netoauth-2.0exchangewebservices

解决方案


我设法摆脱了处理 HTTP 401 并返回 OAuth 以获取新令牌。


推荐阅读