Authentication.h (5063B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #pragma once 4 #include <string> 5 #include <string_view> 6 #include <optional> 7 #include "AppInstallerErrors.h" 8 9 namespace AppInstaller::Authentication 10 { 11 // The authentication type supported 12 enum class AuthenticationType 13 { 14 Unknown, 15 None, 16 MicrosoftEntraId, 17 MicrosoftEntraIdForAzureBlobStorage, 18 }; 19 20 std::string_view AuthenticationTypeToString(AuthenticationType in); 21 AuthenticationType ConvertToAuthenticationType(std::string_view in); 22 23 // The authentication modes 24 enum class AuthenticationMode 25 { 26 Unknown, 27 28 // Always do interactive authentication on first request, following requests may use cached result. 29 Interactive, 30 31 // Try silent flow first. If failed, use interactive flow. 32 SilentPreferred, 33 34 // Only do silent flow. If failed, the authentication failed. 35 Silent, 36 }; 37 38 std::string_view AuthenticationModeToString(AuthenticationMode in); 39 AuthenticationMode ConvertToAuthenticationMode(std::string_view in); 40 41 // Authentication info for Microsoft Entra Id authentication; 42 struct MicrosoftEntraIdAuthenticationInfo 43 { 44 // Resource is required 45 std::string Resource; 46 47 // Scope is optional 48 std::string Scope; 49 50 bool operator<(const MicrosoftEntraIdAuthenticationInfo& other) const; 51 }; 52 53 // Authentication info struct used to initialize Authenticator, this is from source information. 54 struct AuthenticationInfo 55 { 56 AuthenticationType Type = AuthenticationType::None; 57 std::optional<MicrosoftEntraIdAuthenticationInfo> MicrosoftEntraIdInfo; 58 59 bool operator<(const AuthenticationInfo& other) const; 60 61 // Update default values for missing required fields for known authentication type. 62 void UpdateRequiredFieldsIfNecessary(); 63 64 // Validates data integrity against known authentication type. 65 bool ValidateIntegrity() const; 66 }; 67 68 // Authentication arguments struct used to initialize Authenticator, this is from user input. 69 struct AuthenticationArguments 70 { 71 AuthenticationMode Mode = AuthenticationMode::Unknown; 72 73 // Optional. If set, the value will be used to acquire the specific account and also be validated with authentication result. 74 std::string AuthenticationAccount; 75 }; 76 77 // The authentication result 78 struct AuthenticationResult 79 { 80 // Default to failed. S_OK on authentication success. 81 HRESULT Status = APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED; 82 83 // The token result on authentication success. 84 std::string Token; 85 }; 86 87 // Individual authentication provider interface. Authenticator will delegate authentication to authentication provider. 88 struct IAuthenticationProvider 89 { 90 virtual ~IAuthenticationProvider() = default; 91 92 // Authenticate and return string result. 93 virtual AuthenticationResult AuthenticateForToken() = 0; 94 }; 95 96 // The public facing authenticator 97 struct Authenticator 98 { 99 Authenticator(AuthenticationInfo info, AuthenticationArguments args); 100 101 // Authenticate and return string result. 102 AuthenticationResult AuthenticateForToken(); 103 104 private: 105 std::unique_ptr<IAuthenticationProvider> m_authProvider; 106 }; 107 108 // This is the class for authentication window parent window. 109 // When authenticating interactively, some api needs handle to a parent window. 110 // This class will initiate a new thread and create a hidden window but with foreground priority (best effort). 111 // This class handles terminating the window thread on destruction 112 struct AuthenticationWindowBase 113 { 114 // The constructor will initiate the authentication parent window and thread 115 AuthenticationWindowBase(); 116 117 AuthenticationWindowBase(const AuthenticationWindowBase&) = delete; 118 AuthenticationWindowBase& operator=(const AuthenticationWindowBase&) = delete; 119 120 AuthenticationWindowBase(AuthenticationWindowBase&&) = delete; 121 AuthenticationWindowBase& operator=(AuthenticationWindowBase&&) = delete; 122 123 // Get the native window handle 124 HWND GetHandle(); 125 126 // The destructor will terminate the authentication parent window and thread 127 ~AuthenticationWindowBase(); 128 129 private: 130 HWND m_windowHandle; 131 DWORD m_windowThreadId; 132 std::thread m_windowThread; 133 // In case PostThreadMessage() fails, let window thread exit immediately. 134 std::atomic<bool> m_terminateWindowThread = false; 135 136 void InitializeWindowThread(); 137 static LRESULT WINAPI WindowProcessFunction(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 138 }; 139 140 // Create bearer token from a raw token 141 std::string CreateBearerToken(std::string rawToken); 142 }