class _AadHelper(object): def __init__(self, kcsb): if any([kcsb.user_token, kcsb.application_token]): self._token = kcsb.user_token or kcsb.application_token self._authentication_method = AuthenticationMethod.aad_token return authority = kcsb.authority_id or "common" self._kusto_cluster = "{0.scheme}://{0.hostname}".format( urlparse(kcsb.data_source)) self._adal_context = AuthenticationContext( "https://login.microsoftonline.com/{0}".format(authority)) self._username = None if all([kcsb.aad_user_id, kcsb.password]): self._authentication_method = AuthenticationMethod.aad_username_password self._client_id = "db662dc1-0cfe-4e1c-a843-19a68e65be58" self._username = kcsb.aad_user_id self._password = kcsb.password elif all([kcsb.application_client_id, kcsb.application_key]): self._authentication_method = AuthenticationMethod.aad_application_key self._client_id = kcsb.application_client_id self._client_secret = kcsb.application_key elif all([ kcsb.application_client_id, kcsb.application_certificate, kcsb.application_certificate_thumbprint ]): self._authentication_method = AuthenticationMethod.aad_application_certificate self._client_id = kcsb.application_client_id self._certificate = kcsb.application_certificate self._thumbprint = kcsb.application_certificate_thumbprint else: self._authentication_method = AuthenticationMethod.aad_device_login self._client_id = "db662dc1-0cfe-4e1c-a843-19a68e65be58" def acquire_authorization_header(self): """Acquire tokens from AAD.""" try: return self._acquire_authorization_header() except AdalError as error: if self._authentication_method is AuthenticationMethod.aad_username_password: kwargs = { "username": self._username, "client_id": self._client_id } elif self._authentication_method is AuthenticationMethod.aad_application_key: kwargs = {"client_id": self._client_id} elif self._authentication_method is AuthenticationMethod.aad_device_login: kwargs = {"client_id": self._client_id} elif self._authentication_method is AuthenticationMethod.aad_application_certificate: kwargs = { "client_id": self._client_id, "thumbprint": self._thumbprint } else: raise error kwargs["resource"] = self._kusto_cluster kwargs["authority"] = self._adal_context.authority.url raise KustoAuthenticationError(self._authentication_method.value, error, **kwargs) def _acquire_authorization_header(self): if self._authentication_method is AuthenticationMethod.aad_token: return _get_header("Bearer", self._token) token = self._adal_context.acquire_token(self._kusto_cluster, self._username, self._client_id) if token is not None: expiration_date = dateutil.parser.parse( token[TokenResponseFields.EXPIRES_ON]) if expiration_date > datetime.now() + timedelta(minutes=1): return _get_header_from_dict(token) if TokenResponseFields.REFRESH_TOKEN in token: token = self._adal_context.acquire_token_with_refresh_token( token[TokenResponseFields.REFRESH_TOKEN], self._client_id, self._kusto_cluster) if token is not None: return _get_header_from_dict(token) if self._authentication_method is AuthenticationMethod.aad_username_password: token = self._adal_context.acquire_token_with_username_password( self._kusto_cluster, self._username, self._password, self._client_id) elif self._authentication_method is AuthenticationMethod.aad_application_key: token = self._adal_context.acquire_token_with_client_credentials( self._kusto_cluster, self._client_id, self._client_secret) elif self._authentication_method is AuthenticationMethod.aad_device_login: code = self._adal_context.acquire_user_code( self._kusto_cluster, self._client_id) print(code[OAuth2DeviceCodeResponseParameters.MESSAGE]) webbrowser.open( code[OAuth2DeviceCodeResponseParameters.VERIFICATION_URL]) token = self._adal_context.acquire_token_with_device_code( self._kusto_cluster, code, self._client_id) elif self._authentication_method is AuthenticationMethod.aad_application_certificate: token = self._adal_context.acquire_token_with_client_certificate( self._kusto_cluster, self._client_id, self._certificate, self._thumbprint) else: raise KustoClientError( "Please choose authentication method from azure.kusto.data.security.AuthenticationMethod" ) return _get_header_from_dict(token)
class _MyAadHelper(object): def __init__(self, kcsb): authority = kcsb.authority_id or "common" self._kusto_cluster = "{0.scheme}://{0.hostname}".format( urlparse(kcsb.data_source)) self._adal_context = AuthenticationContext( "https://login.microsoftonline.com/{0}".format(authority)) self._username = None if all([kcsb.aad_user_id, kcsb.password]): self._authentication_method = AuthenticationMethod.aad_username_password self._client_id = "db662dc1-0cfe-4e1c-a843-19a68e65be58" self._username = kcsb.aad_user_id self._password = kcsb.password elif all([kcsb.application_client_id, kcsb.application_key]): self._authentication_method = AuthenticationMethod.aad_application_key self._client_id = kcsb.application_client_id self._client_secret = kcsb.application_key elif all([ kcsb.application_client_id, kcsb.application_certificate, kcsb.application_certificate_thumbprint ]): self._authentication_method = AuthenticationMethod.aad_application_certificate self._client_id = kcsb.application_client_id self._certificate = kcsb.application_certificate self._thumbprint = kcsb.application_certificate_thumbprint else: self._authentication_method = AuthenticationMethod.aad_device_login self._client_id = "db662dc1-0cfe-4e1c-a843-19a68e65be58" def acquire_token(self): """Acquire tokens from AAD.""" token = self._adal_context.acquire_token(self._kusto_cluster, self._username, self._client_id) if token is not None: expiration_date = dateutil.parser.parse( token[TokenResponseFields.EXPIRES_ON]) if expiration_date > datetime.now() + timedelta(minutes=1): return self._get_header(token) if TokenResponseFields.REFRESH_TOKEN in token: token = self._adal_context.acquire_token_with_refresh_token( token[TokenResponseFields.REFRESH_TOKEN], self._client_id, self._kusto_cluster) if token is not None: return self._get_header(token) if self._authentication_method is AuthenticationMethod.aad_username_password: token = self._adal_context.acquire_token_with_username_password( self._kusto_cluster, self._username, self._password, self._client_id) elif self._authentication_method is AuthenticationMethod.aad_application_key: token = self._adal_context.acquire_token_with_client_credentials( self._kusto_cluster, self._client_id, self._client_secret) elif self._authentication_method is AuthenticationMethod.aad_device_login: # print(code[OAuth2DeviceCodeResponseParameters.MESSAGE]) # webbrowser.open(code[OAuth2DeviceCodeResponseParameters.VERIFICATION_URL]) # token = self._adal_context.acquire_token_with_device_code( # self._kusto_cluster, code, self._client_id # ) code = self._adal_context.acquire_user_code( self._kusto_cluster, self._client_id) url = code[OAuth2DeviceCodeResponseParameters.VERIFICATION_URL] device_code = code[ OAuth2DeviceCodeResponseParameters.USER_CODE].strip() html_str = ("""<!DOCTYPE html> <html><body> <!-- h1 id="user_code_p"><b>""" + device_code + """</b><br></h1--> <input id="kqlMagicCodeAuthInput" type="text" readonly style="font-weight: bold; border: none;" size = '""" + str(len(device_code)) + """' value='""" + device_code + """'> <button id='kqlMagicCodeAuth_button', onclick="this.style.visibility='hidden';kqlMagicCodeAuthFunction()">Copy code to clipboard and authenticate</button> <script> var kqlMagicUserCodeAuthWindow = null function kqlMagicCodeAuthFunction() { /* Get the text field */ var copyText = document.getElementById("kqlMagicCodeAuthInput"); /* Select the text field */ copyText.select(); /* Copy the text inside the text field */ document.execCommand("copy"); /* Alert the copied text */ // alert("Copied the text: " + copyText.value); var w = screen.width / 2; var h = screen.height / 2; params = 'width='+w+',height='+h kqlMagicUserCodeAuthWindow = window.open('""" + url + """', 'kqlMagicUserCodeAuthWindow', params); // TODO: save selected cell index, so that the clear will be done on the lince cell } </script> </body></html>""") Display.show_html(html_str) # webbrowser.open(code['verification_url']) try: token = self._adal_context.acquire_token_with_device_code( self._kusto_cluster, code, self._client_id) finally: html_str = """<!DOCTYPE html> <html><body><script> // close authentication window if (kqlMagicUserCodeAuthWindow && kqlMagicUserCodeAuthWindow.opener != null && !kqlMagicUserCodeAuthWindow.closed) { kqlMagicUserCodeAuthWindow.close() } // TODO: make sure, you clear the right cell. BTW, not sure it is a must to do any clearing // clear output cell Jupyter.notebook.clear_output(Jupyter.notebook.get_selected_index()) // TODO: if in run all mode, move to last cell, otherwise move to next cell // move to next cell </script></body></html>""" Display.show_html(html_str) elif self._authentication_method is AuthenticationMethod.aad_application_certificate: token = self._adal_context.acquire_token_with_client_certificate( self._kusto_cluster, self._client_id, self._certificate, self._thumbprint) else: raise KustoClientError( "Please choose authentication method from azure.kusto.data.security.AuthenticationMethod" ) return self._get_header(token) def _get_header(self, token): return "{0} {1}".format(token[TokenResponseFields.TOKEN_TYPE], token[TokenResponseFields.ACCESS_TOKEN])
def authenticate_with_device_code(account_name): """Setup storage tokens by authenticating with device code and use management APIs Args: account_name (str): The storage account name for which to authenticate """ import urllib # pylint: disable=import-outside-toplevel import json # pylint: disable=import-outside-toplevel import os # pylint: disable=import-outside-toplevel from tensorflow.python.platform import tf_logging as log # pylint: disable=import-outside-toplevel try: from adal import AuthenticationContext # pylint: disable=import-outside-toplevel except ModuleNotFoundError: log.error( 'Please install adal library with `python -m pip install -U adal`' 'to use the device code authentication method') return ctx = AuthenticationContext('https://login.microsoftonline.com/common') storage_resource = 'https://management.azure.com/' # Current multi-tenant client registerd in my AzureAD tenant client_id = '8c375311-7f4c-406c-84f8-03dfe11ba2d3' device_code = ctx.acquire_user_code(resource=storage_resource, client_id=client_id) # Display authentication message to user to action in their browser log.warn(device_code['message']) token_response = ctx.acquire_token_with_device_code( resource=storage_resource, user_code_info=device_code, client_id=client_id) headers = {'Authorization': 'Bearer ' + token_response['accessToken']} subscription_list_req = urllib.request.Request( url='https://management.azure.com/subscriptions?api-version=2016-06-01', headers=headers) with urllib.request.urlopen(subscription_list_req) as f: subscriptions = json.load(f) subscriptions = subscriptions['value'] storage_account = None for subscription in subscriptions: url = 'https://management.azure.com/subscriptions/{}/providers/Microsoft.Storage/storageAccounts?api-version=2019-04-01'.format( subscription['subscriptionId']) storage_account_list_req = urllib.request.Request(url=url, headers=headers) with urllib.request.urlopen(storage_account_list_req) as f: storage_accounts = json.load(f) storage_accounts = storage_accounts['value'] account_by_name = [ s for s in storage_accounts if s.get('name') == account_name ] if any(account_by_name): storage_account = account_by_name[0] break if storage_account is None: log.error("Couldn't find storage account {} in any " "available subscription".format(account_name)) return url = 'https://management.azure.com/{}/listKeys?api-version=2019-04-01'.format( storage_account['id']) storage_list_keys_req = urllib.request.Request(url=url, headers=headers, method='POST') with urllib.request.urlopen(storage_list_keys_req) as f: account_keys = json.load(f) os.environ['TF_AZURE_STORAGE_KEY'] = account_keys['keys'][0]['value'] log.info('Successfully set account key environment for {} ' 'storage account'.format(account_name))
class _AadHelper: authentication_method = None auth_context = None msi_auth_context = None username = None kusto_uri = None authority_uri = None client_id = None password = None thumbprint = None private_certificate = None public_certificate = None msi_params = None token_provider = None def __init__(self, kcsb: "KustoConnectionStringBuilder"): self.kusto_uri = "{0.scheme}://{0.hostname}".format( urlparse(kcsb.data_source)) self.username = None if all([kcsb.aad_user_id, kcsb.password]): self.authentication_method = AuthenticationMethod.aad_username_password self.client_id = "db662dc1-0cfe-4e1c-a843-19a68e65be58" self.username = kcsb.aad_user_id self.password = kcsb.password elif all([kcsb.application_client_id, kcsb.application_key]): self.authentication_method = AuthenticationMethod.aad_application_key self.client_id = kcsb.application_client_id self.client_secret = kcsb.application_key elif all([ kcsb.application_client_id, kcsb.application_certificate, kcsb.application_certificate_thumbprint ]): self.client_id = kcsb.application_client_id self.private_certificate = kcsb.application_certificate self.thumbprint = kcsb.application_certificate_thumbprint if all([kcsb.application_public_certificate]): self.public_certificate = kcsb.application_public_certificate self.authentication_method = AuthenticationMethod.aad_application_certificate_sni else: self.authentication_method = AuthenticationMethod.aad_application_certificate elif kcsb.msi_authentication: self.authentication_method = AuthenticationMethod.managed_service_identity self.msi_params = kcsb.msi_parameters return elif any([kcsb.user_token, kcsb.application_token]): self.token = kcsb.user_token or kcsb.application_token self.authentication_method = AuthenticationMethod.aad_token return elif kcsb.az_cli: self.authentication_method = AuthenticationMethod.az_cli_profile return elif kcsb.token_provider: self.authentication_method = AuthenticationMethod.token_provider self.token_provider = kcsb.token_provider else: self.authentication_method = AuthenticationMethod.aad_device_login self.client_id = "db662dc1-0cfe-4e1c-a843-19a68e65be58" authority = kcsb.authority_id or "common" aad_authority_uri = os.environ.get("AadAuthorityUri", CLOUD_LOGIN_URL) self.authority_uri = aad_authority_uri + authority if aad_authority_uri.endswith( "/") else aad_authority_uri + "/" + authority def acquire_authorization_header(self): """Acquire tokens from AAD.""" try: return self._acquire_authorization_header() except (AdalError, KustoClientError) as error: if self.authentication_method is AuthenticationMethod.aad_username_password: kwargs = { "username": self.username, "client_id": self.client_id } elif self.authentication_method is AuthenticationMethod.aad_application_key: kwargs = {"client_id": self.client_id} elif self.authentication_method is AuthenticationMethod.aad_device_login: kwargs = {"client_id": self.client_id} elif self.authentication_method in ( AuthenticationMethod.aad_application_certificate, AuthenticationMethod.aad_application_certificate_sni): kwargs = { "client_id": self.client_id, "thumbprint": self.thumbprint } elif self.authentication_method is AuthenticationMethod.managed_service_identity: kwargs = self.msi_params elif self.authentication_method is AuthenticationMethod.token_provider: kwargs = {} else: raise error kwargs["resource"] = self.kusto_uri if self.authentication_method is AuthenticationMethod.managed_service_identity: kwargs[ "authority"] = AuthenticationMethod.managed_service_identity.value elif self.authentication_method is AuthenticationMethod.token_provider: kwargs["authority"] = AuthenticationMethod.token_provider.value elif self.auth_context is not None: kwargs["authority"] = self.auth_context.authority.url elif self.authentication_method is AuthenticationMethod.az_cli_profile: kwargs["authority"] = AuthenticationMethod.az_cli_profile.value raise KustoAuthenticationError(self.authentication_method.value, error, **kwargs) def _acquire_authorization_header(self) -> str: # Token was provided by caller if self.authentication_method is AuthenticationMethod.aad_token: return _get_header("Bearer", self.token) if self.authentication_method is AuthenticationMethod.token_provider: caller_token = self.token_provider() if not isinstance(caller_token, str): raise KustoClientError( "Token provider returned something that is not a string [" + str(type(caller_token)) + "]") return _get_header("Bearer", caller_token) # Obtain token from MSI endpoint if self.authentication_method == AuthenticationMethod.managed_service_identity: msi_token = self.get_token_from_msi() return _get_header("Bearer", msi_token.token) refresh_token = None if self.authentication_method == AuthenticationMethod.az_cli_profile: stored_token = _get_azure_cli_auth_token() if (TokenResponseFields.REFRESH_TOKEN in stored_token and TokenResponseFields._CLIENT_ID in stored_token and TokenResponseFields._AUTHORITY in stored_token): self.client_id = stored_token[TokenResponseFields._CLIENT_ID] self.username = stored_token[TokenResponseFields.USER_ID] self.authority_uri = stored_token[ TokenResponseFields._AUTHORITY] refresh_token = stored_token[TokenResponseFields.REFRESH_TOKEN] if self.auth_context is None: self.auth_context = AuthenticationContext(self.authority_uri) if refresh_token is not None: token = self.auth_context.acquire_token_with_refresh_token( refresh_token, self.client_id, self.kusto_uri) else: token = self.auth_context.acquire_token(self.kusto_uri, self.username, self.client_id) if token is not None: expiration_date = dateutil.parser.parse( token[TokenResponseFields.EXPIRES_ON]) if expiration_date > datetime.now() + timedelta(minutes=1): return _get_header_from_dict(token) if TokenResponseFields.REFRESH_TOKEN in token: token = self.auth_context.acquire_token_with_refresh_token( token[TokenResponseFields.REFRESH_TOKEN], self.client_id, self.kusto_uri) if token is not None: return _get_header_from_dict(token) # obtain token from AAD if self.authentication_method is AuthenticationMethod.aad_username_password: token = self.auth_context.acquire_token_with_username_password( self.kusto_uri, self.username, self.password, self.client_id) elif self.authentication_method is AuthenticationMethod.aad_application_key: token = self.auth_context.acquire_token_with_client_credentials( self.kusto_uri, self.client_id, self.client_secret) elif self.authentication_method is AuthenticationMethod.aad_device_login: code = self.auth_context.acquire_user_code(self.kusto_uri, self.client_id) print(code[OAuth2DeviceCodeResponseParameters.MESSAGE]) webbrowser.open( code[OAuth2DeviceCodeResponseParameters.VERIFICATION_URL]) token = self.auth_context.acquire_token_with_device_code( self.kusto_uri, code, self.client_id) elif self.authentication_method in ( AuthenticationMethod.aad_application_certificate, AuthenticationMethod.aad_application_certificate): token = self.auth_context.acquire_token_with_client_certificate( self.kusto_uri, self.client_id, self.private_certificate, self.thumbprint, self.public_certificate) else: raise KustoClientError( "Please choose authentication method from azure.kusto.data.security.AuthenticationMethod" ) return _get_header_from_dict(token) def get_token_from_msi(self) -> AccessToken: try: if self.msi_auth_context is None: # Create the MSI Authentication object self.msi_auth_context = ManagedIdentityCredential( **self.msi_params) return self.msi_auth_context.get_token(self.kusto_uri) except Exception as e: raise KustoClientError("Failed to obtain MSI context for [" + str(self.msi_params) + "]\n" + str(e))
class _MyAadHelper(object): def __init__(self, kusto_cluster, client_id=None, client_secret=None, username=None, password=None, authority=None): self.adal_context = AuthenticationContext( 'https://login.windows.net/{0}'.format(authority or 'microsoft.com')) self.kusto_cluster = kusto_cluster self.client_id = client_id or "db662dc1-0cfe-4e1c-a843-19a68e65be58" self.client_secret = client_secret self.username = username self.password = password def acquire_token(self): """ A method to acquire tokens from AAD. """ # print("my_aad_helper_acquire_token") token_response = self.adal_context.acquire_token( self.kusto_cluster, self.username, self.client_id) if token_response is not None: expiration_date = dateutil.parser.parse( token_response['expiresOn']) if expiration_date > datetime.utcnow() + timedelta(minutes=5): return token_response['accessToken'] if self.client_secret is not None and self.client_id is not None: token_response = self.adal_context.acquire_token_with_client_credentials( self.kusto_cluster, self.client_id, self.client_secret) elif self.username is not None and self.password is not None: token_response = self.adal_context.acquire_token_with_username_password( self.kusto_cluster, self.username, self.password, self.client_id) else: code = self.adal_context.acquire_user_code(self.kusto_cluster, self.client_id) url = code['verification_url'] device_code = code["user_code"].strip() html_str = """<!DOCTYPE html> <html><body> <!-- h1 id="user_code_p"><b>""" + device_code + """</b><br></h1--> <input id="kqlMagicCodeAuthInput" type="text" readonly style="font-weight: bold; border: none;" size = '""" + str( len(device_code)) + """' value='""" + device_code + """'> <button id='kqlMagicCodeAuth_button', onclick="this.style.visibility='hidden';kqlMagicCodeAuthFunction()">Copy code to clipboard and authenticate</button> <script> var kqlMagicUserCodeAuthWindow = null function kqlMagicCodeAuthFunction() { /* Get the text field */ var copyText = document.getElementById("kqlMagicCodeAuthInput"); /* Select the text field */ copyText.select(); /* Copy the text inside the text field */ document.execCommand("copy"); /* Alert the copied text */ // alert("Copied the text: " + copyText.value); var w = screen.width / 2; var h = screen.height / 2; params = 'width='+w+',height='+h kqlMagicUserCodeAuthWindow = window.open('""" + url + """', 'kqlMagicUserCodeAuthWindow', params); } </script> </body></html>""" Display.show(html_str) # webbrowser.open(code['verification_url']) try: token_response = self.adal_context.acquire_token_with_device_code( self.kusto_cluster, code, self.client_id) finally: html_str = """<!DOCTYPE html> <html><body><script> // close authentication window if (kqlMagicUserCodeAuthWindow && kqlMagicUserCodeAuthWindow.opener != null && !kqlMagicUserCodeAuthWindow.closed) { kqlMagicUserCodeAuthWindow.close() } // clear output cell Jupyter.notebook.clear_output(Jupyter.notebook.get_selected_index()) // move to next cell </script></body></html>""" Display.show(html_str) return token_response['accessToken']