268 lines
12 KiB
VB.net
268 lines
12 KiB
VB.net
Imports System
|
|
Imports System.IO
|
|
Imports System.Net.Http
|
|
Imports System.Text
|
|
Imports System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel
|
|
Imports Newtonsoft.Json
|
|
Imports sun.security.util
|
|
Imports VERAG_PROG_ALLGEMEIN.cRelayHub
|
|
|
|
Public Class cRelayHubToken
|
|
|
|
Private Shared ReadOnly TOKEN_ENDPOINT_PROD As String = "https://login.singlewindow.io/auth/realms/agsw/protocol/openid-connect/token"
|
|
Private Shared ReadOnly TOKEN_ENDPOINT_TEST As String = "https://dev-kc.singlewindow.io/auth/realms/agsw/protocol/openid-connect/token"
|
|
|
|
Private Shared ReadOnly CLIENT_ID As String = "agsw-admin"
|
|
|
|
Private Shared ReadOnly USERNAME_PROD As String = "dhub@verag.ag"
|
|
Private Shared ReadOnly PASSWORD_PROD As String = "Dhub1234*"
|
|
|
|
Private Shared ReadOnly USERNAME_TEST As String = "andreas.test@test.com"
|
|
Private Shared ReadOnly PASSWORD_TEST As String = "Atez123."
|
|
|
|
Private Const ExpirySkewSeconds As Integer = 60
|
|
|
|
'======================================================================
|
|
' KONFIGURATION
|
|
'======================================================================
|
|
Private Shared Function GetTokenEndpoint(environment As cRelayHubEnvironment) As String
|
|
Select Case environment
|
|
Case cRelayHubEnvironment.TEST
|
|
Return TOKEN_ENDPOINT_TEST
|
|
Case cRelayHubEnvironment.PROD
|
|
Return TOKEN_ENDPOINT_PROD
|
|
Case Else
|
|
Throw New ApplicationException("Unbekannte RelayHub-Umgebung.")
|
|
End Select
|
|
End Function
|
|
|
|
Private Shared Function GetUsername(environment As cRelayHubEnvironment) As String
|
|
Select Case environment
|
|
Case cRelayHubEnvironment.TEST
|
|
Return USERNAME_TEST
|
|
Case cRelayHubEnvironment.PROD
|
|
Return USERNAME_PROD
|
|
Case Else
|
|
Throw New ApplicationException("Unbekannte RelayHub-Umgebung.")
|
|
End Select
|
|
End Function
|
|
|
|
Private Shared Function GetPassword(environment As cRelayHubEnvironment) As String
|
|
Select Case environment
|
|
Case cRelayHubEnvironment.TEST
|
|
Return PASSWORD_TEST
|
|
Case cRelayHubEnvironment.PROD
|
|
Return PASSWORD_PROD
|
|
Case Else
|
|
Throw New ApplicationException("Unbekannte RelayHub-Umgebung.")
|
|
End Select
|
|
End Function
|
|
|
|
Private Shared Function GetStorePath(environment As cRelayHubEnvironment) As String
|
|
Dim fileName As String = If(environment = cRelayHubEnvironment.TEST, "token_test.json", "token_prod.json")
|
|
Return Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData), "RelayHub", fileName)
|
|
End Function
|
|
|
|
'======================================================================
|
|
' ACCESS TOKEN
|
|
'======================================================================
|
|
Public Shared Function GetAccessToken(environment As cRelayHubEnvironment) As String
|
|
Dim store = LoadStore(environment)
|
|
|
|
If store IsNot Nothing AndAlso Not String.IsNullOrWhiteSpace(store.AccessToken) Then
|
|
If store.ExpiresAtUtc > DateTimeOffset.UtcNow.AddSeconds(ExpirySkewSeconds) Then Return store.AccessToken
|
|
End If
|
|
|
|
If store IsNot Nothing AndAlso Not String.IsNullOrWhiteSpace(store.RefreshToken) Then store = TryRefresh(store.RefreshToken, environment)
|
|
|
|
If store Is Nothing OrElse String.IsNullOrWhiteSpace(store.AccessToken) Then store = PasswordLogin(environment)
|
|
|
|
If store Is Nothing OrElse String.IsNullOrWhiteSpace(store.AccessToken) Then Throw New ApplicationException("Konnte keinen gültigen Access Token erhalten (" & environment.ToString() & ").")
|
|
|
|
SaveStore(store, environment)
|
|
Return store.AccessToken
|
|
End Function
|
|
|
|
'======================================================================
|
|
' LOGIN
|
|
'======================================================================
|
|
Private Shared Function PasswordLogin(environment As cRelayHubEnvironment) As TokenStore
|
|
Dim form = New Dictionary(Of String, String) From {
|
|
{"grant_type", "password"},
|
|
{"username", GetUsername(environment)},
|
|
{"password", GetPassword(environment)},
|
|
{"client_id", CLIENT_ID}
|
|
}
|
|
|
|
Dim resp = PostForm(form, environment)
|
|
Return ParseTokenResponse(resp, environment)
|
|
End Function
|
|
|
|
'======================================================================
|
|
' REFRESH
|
|
'======================================================================
|
|
Private Shared Function TryRefresh(refreshToken As String, environment As cRelayHubEnvironment) As TokenStore
|
|
Try
|
|
Dim form = New Dictionary(Of String, String) From {
|
|
{"grant_type", "refresh_token"},
|
|
{"refresh_token", refreshToken},
|
|
{"client_id", CLIENT_ID}
|
|
}
|
|
|
|
Dim resp = PostForm(form, environment)
|
|
Dim token = ParseTokenResponse(resp, environment)
|
|
|
|
If Not String.IsNullOrWhiteSpace(token.AccessToken) Then
|
|
SaveStore(token, environment)
|
|
Return token
|
|
End If
|
|
Catch ex As Exception
|
|
Console.WriteLine("Token Refresh fehlgeschlagen (" & environment.ToString() & "): " & ex.Message)
|
|
End Try
|
|
|
|
Return Nothing
|
|
End Function
|
|
|
|
'======================================================================
|
|
' HTTP
|
|
'======================================================================
|
|
Private Shared Function PostForm(formFields As Dictionary(Of String, String), environment As cRelayHubEnvironment) As String
|
|
Using client As New HttpClient()
|
|
Using content As New FormUrlEncodedContent(formFields)
|
|
Dim tokenEndpoint As String = GetTokenEndpoint(environment)
|
|
|
|
Dim username As String = GetUsername(environment)
|
|
Dim password As String = GetPassword(environment)
|
|
|
|
Console.WriteLine("")
|
|
Console.WriteLine("==================================================")
|
|
Console.WriteLine(" RELAYHUB TOKEN REQUEST")
|
|
Console.WriteLine("==================================================")
|
|
Console.WriteLine("Environment : " & environment.ToString())
|
|
Console.WriteLine("Token Endpoint : " & tokenEndpoint)
|
|
Console.WriteLine("Client ID : " & CLIENT_ID)
|
|
'Console.WriteLine("Username : " & username)
|
|
'Console.WriteLine("Password : " & password)
|
|
'Console.WriteLine("Password Länge : " & If(password Is Nothing, 0, password.Length))
|
|
'Console.WriteLine("Grant Type : " & If(formFields.ContainsKey("grant_type"), formFields("grant_type"), "<nicht gesetzt>"))
|
|
'Console.WriteLine("Token Store : " & GetStorePath(environment))
|
|
'Console.WriteLine("==================================================")
|
|
|
|
|
|
Dim response = client.PostAsync(tokenEndpoint, content).Result
|
|
Dim body = response.Content.ReadAsStringAsync().Result
|
|
|
|
If Not response.IsSuccessStatusCode Then Throw New ApplicationException("Token-Endpoint Fehler (" & environment.ToString() & " / " & CInt(response.StatusCode) & "): " & body)
|
|
|
|
Return body
|
|
End Using
|
|
End Using
|
|
End Function
|
|
|
|
'======================================================================
|
|
' TOKEN RESPONSE
|
|
'======================================================================
|
|
Private Shared Function ParseTokenResponse(json As String, environment As cRelayHubEnvironment) As TokenStore
|
|
Dim r = JsonConvert.DeserializeObject(Of TokenResponse)(json)
|
|
|
|
If r Is Nothing OrElse String.IsNullOrWhiteSpace(r.access_token) Then Throw New ApplicationException("Token-Antwort ungültig oder ohne access_token.")
|
|
|
|
Dim now = DateTimeOffset.UtcNow
|
|
Dim expiresIn = If(r.expires_in <= 0, 3600, r.expires_in)
|
|
|
|
Dim store = New TokenStore With {
|
|
.AccessToken = r.access_token.Trim(),
|
|
.RefreshToken = If(r.refresh_token, String.Empty),
|
|
.ExpiresAtUtc = now.AddSeconds(expiresIn)
|
|
}
|
|
|
|
Console.WriteLine("== Neuer RelayHub Token ==")
|
|
Console.WriteLine("Environment: " & environment.ToString())
|
|
Console.WriteLine("Gültig bis UTC: " & store.ExpiresAtUtc.ToString("yyyy-MM-dd HH:mm:ss"))
|
|
|
|
Return store
|
|
End Function
|
|
|
|
'======================================================================
|
|
' TOKEN LADEN
|
|
'======================================================================
|
|
Private Shared Function LoadStore(environment As cRelayHubEnvironment) As TokenStore
|
|
Try
|
|
Dim storePath As String = GetStorePath(environment)
|
|
|
|
If File.Exists(storePath) Then
|
|
Dim json = File.ReadAllText(storePath, Encoding.UTF8)
|
|
Dim s = JsonConvert.DeserializeObject(Of TokenStore)(json)
|
|
|
|
If s IsNot Nothing Then
|
|
Console.WriteLine("== Token aus Datei geladen ==")
|
|
Console.WriteLine("Environment: " & environment.ToString())
|
|
Console.WriteLine("Gültig bis UTC: " & s.ExpiresAtUtc.ToString("yyyy-MM-dd HH:mm:ss"))
|
|
End If
|
|
|
|
Return s
|
|
Else
|
|
Console.WriteLine("Keine Token-Datei für " & environment.ToString() & " vorhanden.")
|
|
End If
|
|
Catch ex As Exception
|
|
Console.WriteLine("Fehler beim Laden der Token-Datei: " & ex.Message)
|
|
End Try
|
|
|
|
Return Nothing
|
|
End Function
|
|
|
|
'======================================================================
|
|
' TOKEN SPEICHERN
|
|
'======================================================================
|
|
Private Shared Sub SaveStore(store As TokenStore, environment As cRelayHubEnvironment)
|
|
Try
|
|
Dim storePath As String = GetStorePath(environment)
|
|
Dim dir = Path.GetDirectoryName(storePath)
|
|
|
|
If Not Directory.Exists(dir) Then Directory.CreateDirectory(dir)
|
|
|
|
Dim json = JsonConvert.SerializeObject(store, Formatting.Indented)
|
|
File.WriteAllText(storePath, json, Encoding.UTF8)
|
|
|
|
Console.WriteLine("Token-Datei gespeichert: " & storePath)
|
|
Catch ex As Exception
|
|
Console.WriteLine("Fehler beim Speichern der Token-Datei: " & ex.Message)
|
|
End Try
|
|
End Sub
|
|
|
|
'======================================================================
|
|
' TOKEN LÖSCHEN
|
|
'======================================================================
|
|
Private Shared Sub Delete_Store(Optional environment As cRelayHubEnvironment = cRelayHubEnvironment.PROD)
|
|
Try
|
|
Dim storePath As String = GetStorePath(environment)
|
|
If File.Exists(storePath) Then File.Delete(storePath)
|
|
Console.WriteLine("Token-Datei gelöscht: " & storePath)
|
|
Catch ex As Exception
|
|
Console.WriteLine("Fehler beim Löschen der Token-Datei: " & ex.Message)
|
|
End Try
|
|
End Sub
|
|
Public Shared Sub DeleteAllStores()
|
|
Delete_Store(cRelayHubEnvironment.TEST)
|
|
Delete_Store(cRelayHubEnvironment.PROD)
|
|
End Sub
|
|
|
|
'======================================================================
|
|
' DTOs
|
|
'======================================================================
|
|
Private Class TokenResponse
|
|
Public Property access_token As String
|
|
Public Property expires_in As Integer
|
|
Public Property refresh_expires_in As Integer
|
|
Public Property refresh_token As String
|
|
Public Property token_type As String
|
|
Public Property scope As String
|
|
End Class
|
|
|
|
Private Class TokenStore
|
|
Public Property AccessToken As String
|
|
Public Property RefreshToken As String
|
|
Public Property ExpiresAtUtc As DateTimeOffset
|
|
End Class
|
|
|
|
End Class |