Messaging: First working version of OAuth2

This commit is contained in:
Jonathan Jenne 2023-09-06 10:24:46 +02:00
parent 6f33261101
commit e8974376c5
4 changed files with 59 additions and 17 deletions

View File

@ -30,11 +30,16 @@ Namespace Mail
End Sub
Public Function Connect(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String) As MailSession.SessionInfo
Return MailSession.ConnectToServer(pServer, pPort, pUser, pPassword, pAuthType, New MailSession.MailSessionOptions)
Return MailSession.ConnectToServerWithBasicAuth(pServer, pPort, pUser, pPassword, pAuthType, New MailSession.MailSessionOptions)
End Function
Public Function ConnectToO365(pUser As String, pClientId As String, pTenantId As String, pClientSecret As String)
Dim oOptions = New MailSession.MailSessionOptions With {.EnableTls1_2 = True}
Return MailSession.ConnectToServerWithO365OAuth(pUser, pClientId, pTenantId, pClientSecret, oOptions)
End Function
Public Function Connect(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String, pOptions As MailSession.MailSessionOptions) As MailSession.SessionInfo
Return MailSession.ConnectToServer(pServer, pPort, pUser, pPassword, pAuthType, pOptions)
Return MailSession.ConnectToServerWithBasicAuth(pServer, pPort, pUser, pPassword, pAuthType, pOptions)
End Function
Public Function Disconnect() As Boolean

View File

@ -20,11 +20,11 @@ Namespace Mail
End Sub
Public Function Connect(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String) As MailSession.SessionInfo
Return MailSession.ConnectToServer(pServer, pPort, pUser, pPassword, pAuthType, New MailSession.MailSessionOptions)
Return MailSession.ConnectToServerWithBasicAuth(pServer, pPort, pUser, pPassword, pAuthType, New MailSession.MailSessionOptions)
End Function
Public Function Connect(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String, pOptions As MailSession.MailSessionOptions) As MailSession.SessionInfo
Return MailSession.ConnectToServer(pServer, pPort, pUser, pPassword, pAuthType, pOptions)
Return MailSession.ConnectToServerWithBasicAuth(pServer, pPort, pUser, pPassword, pAuthType, pOptions)
End Function
Public Function Disconnect() As Boolean

View File

@ -69,7 +69,7 @@ Namespace Mail
''' <param name="pPassword"></param>
''' <param name="pAuthType"></param>
''' <returns></returns>
Public Function ConnectToServer(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String, pOptions As MailSessionOptions) As SessionInfo
Public Function ConnectToServerWithBasicAuth(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String, pOptions As MailSessionOptions) As SessionInfo
Dim oSession = New SessionInfo With {
.Server = pServer,
.Port = pPort,
@ -91,6 +91,30 @@ Namespace Mail
Return ConnectToServer(oSession, pOptions)
End Function
Public Function ConnectToServerWithO365OAuth(pUser As String, pClientId As String, pTenantId As String, pClientSecret As String, pOptions As MailSessionOptions) As SessionInfo
Dim oSession = New SessionInfo With {
.Server = OAuth2.O365_SERVER,
.ClientId = pClientId,
.ClientSecret = pClientSecret,
.TenantId = pTenantId,
.User = pUser,
.AuthType = AUTH_OAUTH2
}
Logger.Debug("Connecting to Server..")
Logger.Debug("Server: [{0}]", oSession.Server)
Logger.Debug("User: [{0}]", oSession.User)
Logger.Debug("ClientId: [{0}]", oSession.ClientId)
Logger.Debug("TenantId: [{0}]", oSession.TenantId)
Logger.Debug("AuthType: [{0}]", oSession.AuthType)
_Session = oSession
Logger.Debug("Initializing Connection with Auth type [{0}].", oSession.AuthType)
Return ConnectToServer(oSession, pOptions)
End Function
Private Function ConnectToServer(pSession As SessionInfo, pOptions As MailSessionOptions) As SessionInfo
AddHandler Client.ServerCertificateValidate, AddressOf Session_ServerCertificateValidate
@ -125,6 +149,8 @@ Namespace Mail
Try
If TypeOf Client Is Imap Then
Dim oClient As Imap = Client
Logger.Debug("Connecting with [ConnectSSL] on [{0}]", pSession.Server)
oClient.ConnectSSL(pSession.Server)
Else
Throw New ApplicationException("Only OAuth2 for IMAP is not yet supported!")
@ -205,7 +231,7 @@ Namespace Mail
If pSession.AuthType = AUTH_OAUTH2 Then
' SessionInfo.Password will be the access token that was obtained
' in the OAuth2 flow before
DoUseBestLogin_OAuth2(Client, pSession.User, pSession.Password)
DoUseBestLogin_OAuth2(Client, pSession)
Else
DoUseBestLogin_BasicAuth(Client, pSession.User, pSession.Password)
End If
@ -245,7 +271,7 @@ Namespace Mail
End Function
Public Function TestLogin(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String, pOptions As MailSessionOptions) As Boolean
Dim oInfo = ConnectToServer(pServer, pPort, pUser, pPassword, pAuthType, pOptions)
Dim oInfo = ConnectToServerWithBasicAuth(pServer, pPort, pUser, pPassword, pAuthType, pOptions)
If oInfo.Connected Then
If DisconnectFromServer() Then
Return True
@ -259,7 +285,6 @@ Namespace Mail
End If
End Function
Private Function SupportsSTARTTLS(pClient As ClientBase)
If TypeOf pClient Is Smtp Then
Return DirectCast(pClient, Smtp).SupportedExtensions.Contains(SmtpExtension.StartTLS)
@ -282,6 +307,8 @@ Namespace Mail
End Sub
Private Sub DoUseBestLogin_BasicAuth(pClient As ClientBase, pUserName As String, pPassword As String)
Logger.Debug("Logging in with Simple Auth")
If TypeOf pClient Is Smtp Then
DirectCast(pClient, Smtp).UseBestLogin(pUserName, pPassword)
ElseIf TypeOf pClient Is Imap Then
@ -291,9 +318,14 @@ Namespace Mail
End If
End Sub
Private Sub DoUseBestLogin_OAuth2(pClient As ClientBase, pUserName As String, pAccessToken As String)
Private Sub DoUseBestLogin_OAuth2(pClient As ClientBase, pSession As SessionInfo)
Logger.Debug("Logging in with O365 OAuth2")
If TypeOf pClient Is Imap Then
DirectCast(pClient, Imap).LoginOAUTH2(pUserName, pAccessToken)
Dim oOAuth = New OAuth2(LogConfig, pSession.TenantId, pSession.ClientId, pSession.ClientSecret)
Dim oAccessToken = oOAuth.GetAccessToken()
DirectCast(pClient, Imap).LoginOAUTH2(pSession.User, oAccessToken)
Else
Logger.Error("Unknown session type: [{0}]", pClient.GetType.ToString)
End If

View File

@ -1,6 +1,7 @@
Imports DigitalData.Modules.Base
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Messaging.Mail.MailSession
Imports Limilabs.Client.IMAP
Imports Microsoft.Identity.Client
Public Class OAuth2
@ -27,21 +28,25 @@ Public Class OAuth2
ClientSecret = pClientSecret
End Sub
Private Async Function GetAccessToken(pSession As SessionInfo) As Task(Of String)
Public Function GetAccessToken() As String
Logger.Debug("Fetching Access Token..")
Try
' Create the application, which is defined in
' Microsoft.Identity.Client
Dim oApp = ConfidentialClientApplicationBuilder.
Create(pSession.ClientId).
WithTenantId(pSession.TenantId).
WithClientSecret(pSession.ClientSecret).
Create(ClientId).
WithTenantId(TenantId).
WithClientSecret(ClientSecret).
Build()
' Request an access token
Dim oScopes = New List(Of String) From {O365_SCOPE}
Dim oResult = Await oApp.
Dim oResult = oApp.
AcquireTokenForClient(oScopes).
ExecuteAsync()
ExecuteAsync().Result
Logger.Debug("Access Token fetched.")
Return oResult.AccessToken
Catch ex As Exception