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 End Sub
Public Function Connect(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String) As MailSession.SessionInfo 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 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 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 End Function
Public Function Disconnect() As Boolean Public Function Disconnect() As Boolean

View File

@ -20,11 +20,11 @@ Namespace Mail
End Sub End Sub
Public Function Connect(pServer As String, pPort As Integer, pUser As String, pPassword As String, pAuthType As String) As MailSession.SessionInfo 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 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 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 End Function
Public Function Disconnect() As Boolean Public Function Disconnect() As Boolean

View File

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

View File

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