class UserPassTokenProvider(TokenProviderBase): """ Acquire a token from MSAL with username and password """ def __init__(self, kusto_uri: str, authority_uri: str, username: str, password: str): super().__init__(kusto_uri) self._msal_client = None self._auth = authority_uri self._user = username self._pass = password @staticmethod def name() -> str: return "UserPassTokenProvider" def context(self) -> dict: return {"authority": self._auth, "client_id": self._cloud_info.kusto_client_app_id, "username": self._user} def _init_impl(self): self._msal_client = PublicClientApplication(client_id=self._cloud_info.kusto_client_app_id, authority=self._auth) def _get_token_impl(self) -> dict: token = self._msal_client.acquire_token_by_username_password(username=self._user, password=self._pass, scopes=self._scopes) return self._valid_token_or_throw(token) def _get_token_from_cache_impl(self) -> dict: account = None if self._user is not None: accounts = self._msal_client.get_accounts(self._user) if len(accounts) > 0: account = accounts[0] token = self._msal_client.acquire_token_silent(scopes=self._scopes, account=account) return self._valid_token_or_none(token)
def getPublicAccessToken(self) -> Optional[str]: # Initialise the app if not already exist if not self.app: print("Initialise msal connection app") self.app = PublicClientApplication(client_id=self.app_id, authority=self.authority) result = None accounts = self.app.get_accounts() if accounts: # TODO: need to pick the relevant account to proceed chosen = accounts[0] # try to get the token from cache if already exist result = self.app.acquire_token_silent(scopes=self.scopes, account=chosen) if not result: print( "No suitable token exists in cache. Let's get a new one from AAD." ) if self.username and self.password: result = self.getUsernamePasswordAccessToken() else: result = self.getDeviceFlowAccessToken() if "access_token" in result: return result["access_token"] return None
class InteractiveLoginTokenProvider(TokenProviderBase): """Acquire a token from MSAL with Device Login flow""" def __init__(self, kusto_uri: str, authority_uri: str, login_hint: Optional[str] = None, domain_hint: Optional[str] = None): super().__init__(kusto_uri) self._msal_client = None self._auth = authority_uri self._login_hint = login_hint self._domain_hint = domain_hint self._account = None @staticmethod def name() -> str: return "InteractiveLoginTokenProvider" def context(self) -> dict: return {"authority": self._auth, "client_id": self._cloud_info.kusto_client_app_id} def _init_impl(self): self._msal_client = PublicClientApplication(client_id=self._cloud_info.kusto_client_app_id, authority=self._auth) def _get_token_impl(self) -> dict: token = self._msal_client.acquire_token_interactive( scopes=self._scopes, prompt=TokenConstants.MSAL_INTERACTIVE_PROMPT, login_hint=self._login_hint, domain_hint=self._domain_hint ) return self._valid_token_or_throw(token) def _get_token_from_cache_impl(self) -> dict: account = None accounts = self._msal_client.get_accounts(self._login_hint) if len(accounts) > 0: account = accounts[0] token = self._msal_client.acquire_token_silent(scopes=self._scopes, account=account) return self._valid_token_or_none(token)
async def get_token_for_teams_user(self): if (os.getenv("SKIP_INT_IDENTITY_EXCHANGE_TOKEN_TEST") == "true"): print("Skipping the Get Access Token for Teams User sample") return from azure.communication.identity.aio import CommunicationIdentityClient if self.client_id is not None and self.client_secret is not None and self.tenant_id is not None: from azure.identity.aio import DefaultAzureCredential endpoint, _ = parse_connection_str(self.connection_string) identity_client = CommunicationIdentityClient( endpoint, DefaultAzureCredential()) else: identity_client = CommunicationIdentityClient.from_connection_string( self.connection_string) async with identity_client: msal_app = PublicClientApplication(client_id=self.m365_app_id, authority="{}/{}".format( self.m365_aad_authority, self.m365_aad_tenant)) result = msal_app.acquire_token_by_username_password( username=self.msal_username, password=self.msal_password, scopes=[self.m365_scope]) add_token = result["access_token"] print("AAD access token of a Teams User: "******"AAD access token of a Teams User: "******"Token issued with value: " + tokenresponse.token)
def _get_token_impl(self) -> dict: # try and obtain the refresh token from AzCli refresh_token = None token = None stored_token = self._get_azure_cli_auth_token() if TokenConstants.AZ_REFRESH_TOKEN in stored_token and TokenConstants.AZ_CLIENT_ID in stored_token and TokenConstants.AZ_AUTHORITY in stored_token: refresh_token = stored_token[TokenConstants.AZ_REFRESH_TOKEN] self._client_id = stored_token[TokenConstants.AZ_CLIENT_ID] self._authority_uri = stored_token[TokenConstants.AZ_AUTHORITY] self._username = stored_token[TokenConstants.AZ_USER_ID] else: raise KustoClientError( "Unable to obtain a refresh token from Az-Cli. Calling 'az login' may fix this issue." ) if self._msal_client is None: self._msal_client = PublicClientApplication( client_id=self._client_id, authority=self._authority_uri) try: token = self._msal_client.acquire_token_by_refresh_token( refresh_token, self._scopes) except Exception as ex: raise KustoClientError( "Unable to obtain with Az-Cli refresh token. Calling 'az login' may fix this issue.\n" + str(ex)) return self._valid_token_or_throw( token, "Calling 'az login' may fix this issue.")
def __init__(self, tenant_id: Optional[str] = None): # cache file should be written to home directory home = os.path.expanduser('~') if home: self._cache_file = os.path.join(home, '.bonsaicache') else: raise RuntimeError('Unable to find home directory.') self.cache = TokenCache(self._cache_file) retry_count = 1 effective_tenant_id = tenant_id if tenant_id is not None and tenant_id != 'None' else 'organizations' _AAD_AUTHORITY = 'https://login.microsoftonline.com/' + effective_tenant_id while True: try: self._app = PublicClientApplication(_AAD_CLIENT_ID, authority=_AAD_AUTHORITY, token_cache=self.cache) if self._app: break except ConnectionError as e: log.info('ConnectionError on attempt {} to ' 'create msal PublicClientApplication, ' 'retrying...'.format(retry_count)) if retry_count >= 5: raise e retry_count += 1
class DeviceLoginTokenProvider(CloudInfoTokenProvider): """Acquire a token from MSAL with Device Login flow""" def __init__(self, kusto_uri: str, authority_id: str, device_code_callback=None, is_async: bool = False): super().__init__(kusto_uri, is_async) self._msal_client = None self._auth = authority_id self._account = None self._device_code_callback = device_code_callback @staticmethod def name() -> str: return "DeviceLoginTokenProvider" def _context_impl(self) -> dict: return { "authority": self._cloud_info.authority_uri(self._auth), "client_id": self._cloud_info.kusto_client_app_id } def _init_impl(self): self._msal_client = PublicClientApplication( client_id=self._cloud_info.kusto_client_app_id, authority=self._cloud_info.authority_uri(self._auth), proxies=self._proxy_dict) def _get_token_impl(self) -> Optional[dict]: flow = self._msal_client.initiate_device_flow(scopes=self._scopes) try: if self._device_code_callback: self._device_code_callback( flow[TokenConstants.MSAL_DEVICE_MSG]) else: print(flow[TokenConstants.MSAL_DEVICE_MSG]) webbrowser.open(flow[TokenConstants.MSAL_DEVICE_URI]) except KeyError: raise KustoClientError("Failed to initiate device code flow") token = self._msal_client.acquire_token_by_device_flow(flow) # Keep the account for silent login if self._valid_token_or_none(token) is not None: accounts = self._msal_client.get_accounts() if len(accounts) == 1: self._account = accounts[0] return self._valid_token_or_throw(token) def _get_token_from_cache_impl(self) -> dict: token = self._msal_client.acquire_token_silent(scopes=self._scopes, account=self._account) return self._valid_token_or_none(token)
async def get_current_user( auth_settings: AuthSettings = Depends(get_auth_settings), msal_app: msal.PublicClientApplication = Depends(get_public_app), authorization: Optional[str] = Header(None), x_ms_token_aad_id_token: Optional[str] = Header(None), ): tenant = urlparse(auth_settings.b2c_endpoint).path.lstrip('/') scopes = [ f'https://{tenant}/{auth_settings.b2c_client_id}/user.impersonate', ] if payload := msal_app.acquire_token_silent(scopes, None): return f'{payload["given_name"]} {payload["family_name"]}'
def get_token_from_cache(app: msal.PublicClientApplication, token_scope: List[str]) -> Union[str, None]: """Try to get an API access token from a local cache. If the access token is expired a refresh token will automatically be used to get a new access token. If the refresh token is expired then the user will have to reauthenticate.""" accounts = app.get_accounts() if accounts: result = app.acquire_token_silent(token_scope, account=accounts[0]) # Method returns None if no token can be acquired if result and "access_token" in result: return result["access_token"] else: return None
def _get_token(): auth_client = PublicClientApplication( client_id=current_app.config["AUTH_CLIENT_ID"], authority=current_app.config["AUTH_CLIENT_TENANCY"]) auth_flow = auth_client.initiate_device_flow( scopes=current_app.config["AUTH_CLIENT_SCOPES"]) click.pause( f"To sign-in, visit 'https://microsoft.com/devicelogin', enter this code '{auth_flow['user_code']}' and then press any key..." ) auth_payload = auth_client.acquire_token_by_device_flow(auth_flow) current_app.config["AUTH_TOKEN"] = auth_payload["access_token"] click.echo(current_app.config["AUTH_TOKEN"]) click.echo(f"Ok. Access token set.")
def generate_teams_user_aad_token(self): if self.is_playback(): teams_user_aad_token = "sanitized" else: msal_app = PublicClientApplication(client_id=self.m365_app_id, authority="{}/{}".format( self.m365_aad_authority, self.m365_aad_tenant)) result = msal_app.acquire_token_by_username_password( username=self.msal_username, password=self.msal_password, scopes=[self.m365_scope]) teams_user_aad_token = result["access_token"] return teams_user_aad_token
def _msal_app(self): """A PublicClientApplication instance for user login/logout. The instance is lazily created. """ if not self._msal_app_instance: self._msal_app_instance = PublicClientApplication(self.client_id, **self._msal_app_kwargs) return self._msal_app_instance
def Authorize(self): bSDD_ClientID = '4aba821f-d4ff-498b-a462-c2837dbbba70' bSDD_Scope = "https://buildingsmartservices.onmicrosoft.com/api/read" from msal import PublicClientApplication bSDD_authority = 'https://buildingsmartservices.b2clogin.com/tfp/buildingsmartservices.onmicrosoft.com/b2c_1_signupsignin' app = PublicClientApplication( bSDD_ClientID, authority=bSDD_authority ) #need localhost redirection on azure portal for the client ID flow = app.initiate_auth_code_flow(scopes=[bSDD_Scope]) self.Token = app.acquire_token_interactive(scopes=[bSDD_Scope]) print('logged in')
def get_token_by_device_flow(app: msal.PublicClientApplication, token_scope: List[str]) -> str: flow = app.initiate_device_flow(scopes=token_scope) if "user_code" not in flow: raise ValueError("Fail to create device flow. Err: %s" % json.dumps(flow, indent=4)) print(flow["message"]) print( "Program execution will continue automatically after authentication.") # This function polls every 5 seconds to see if the user has completed the authentication result = app.acquire_token_by_device_flow(flow) if "access_token" in result: return result["access_token"] else: print(result.get("error")) print(result.get("error_description")) raise ValueError()
def __init__(self, url: str): self._base_url = url self.cache = BonsaiTokenCache() atexit.register(write_cache_to_file, self.cache) retry_count = 1 while True: try: self._app = PublicClientApplication(_AAD_CLIENT_ID, authority=_AAD_AUTHORITY, token_cache=self.cache) if self._app: break except ConnectionError as e: log.info('ConnectionError on attempt {} to ' 'create msal PublicClientApplication, ' 'retrying...'.format(retry_count)) if retry_count >= 5: raise e retry_count += 1
def _get_token_impl(self) -> dict: # try and obtain the refresh token from AzCli refresh_token = None token = None stored_token = self._get_azure_cli_auth_token() if TokenConstants.AZ_REFRESH_TOKEN in stored_token and TokenConstants.AZ_CLIENT_ID in stored_token and TokenConstants.AZ_AUTHORITY in stored_token: refresh_token = stored_token[TokenConstants.AZ_REFRESH_TOKEN] self._client_id = stored_token[TokenConstants.AZ_CLIENT_ID] self._authority_uri = stored_token[TokenConstants.AZ_AUTHORITY] self._username = stored_token[TokenConstants.AZ_USER_ID] else: raise KustoClientError("Unable to obtain a refresh token from Az-Cli") if self._msal_client is None: self._msal_client = PublicClientApplication(client_id=self._client_id, authority=self._authority_uri) if refresh_token is not None: token = self._msal_client.acquire_token_by_refresh_token(refresh_token, self._scopes) return self._valid_token_or_throw(token)
def auth_callback(): if request.args.get("state") != session.get("state"): return "Sign-in failed, state doesn't match.", 403 if request.args.get("error"): return request.args.get("error"), 403 if not request.args.get("code"): return "Sign-in failed, no auth code.", 403 auth_client = PublicClientApplication( client_id=app.config["AUTH_CLIENT_ID"], authority=current_app.config["AUTH_CLIENT_TENANCY"]) result = auth_client.acquire_token_by_auth_code_flow( auth_code_flow=session.get("auth_code_flow"), auth_response=request.args, scopes=current_app.config["AUTH_CLIENT_SCOPES"], ) if result.get("error"): return "Sign-in failed.", 403 if not result.get("access_token"): return "Sign-in failed, no access token.", 403 session["access_token"] = result.get("access_token") return "Signed-in"
def get_access_token(self): result = None app = PublicClientApplication( self.config['CLIENT_ID'], authority=self.config['AUTHORITY'], ) accounts = app.get_accounts() if accounts: chosen_account = accounts[0] result = app.acquire_token_silent(self.config['scopes'], account=chosen_account) if not result: result = app.acquire_token_by_username_password( self.config['USERNAME'], self.config['SECRET'], scopes=self.config['scopes'] ) print(result) return result['access_token']
def get_access_token(self): result = None app = PublicClientApplication( self.config['CLIENT_ID'], authority=self.config['AUTHORITY'], ) accounts = app.get_accounts() if accounts: chosen_account = accounts[0] result = app.acquire_token_silent(self.config['scopes'], account=chosen_account) if not result: result = app.acquire_token_by_username_password( self.config['USERNAME'], self.config['SECRET'], scopes=self.config['scopes']) print(result) return result['access_token']
def msal_connect(self): app = PublicClientApplication(self.client_id, authority=self.authority) result = None accounts = app.get_accounts() if accounts: # If so, you could then somehow display these accounts and let end user choose print("Pick the account you want to use to proceed:") for a in accounts: print(a["username"]) # Assuming the end user chose this one chosen = accounts[0] # Now let's try to find a token in cache for this account result = app.acquire_token_silent(self.scopes, account=chosen) if not result: # So no suitable token exists in cache. Let's get a new one from AAD. result = app.acquire_token_by_username_password(self.username, self.password, scopes=self.scopes) return result
def TestInput(input_bytes): if len(input_bytes) < 32: return fdp = atheris.FuzzedDataProvider(input_bytes) authority = AuthorityBuilder(fdp.ConsumeString(50), fdp.ConsumeString(50)) try: app = PublicClientApplication( client_id=fdp.ConsumeString(32), authority=authority, http_client=FuzzHttpClient(fdp) # Use fake Fuzz HTTP client ) app.get_accounts() except (ValueError, KeyError) as e: error_list = [ "tenant_discovery_endpoint", "Invalid IPv6 URL", "should consist of an https url with a minimum of one segment in a path", "netloc" ] if not is_expected(error_list, str(e)): raise e cert = "-----BEGIN CERTIFICATE-----%s-----END CERTIFICATE-----" % fdp.ConsumeString( 200) extract_certs(cert)
def _get_client_application(self, **kwargs): tenant_id = resolve_tenant(self._tenant_id, **kwargs) if tenant_id not in self._client_applications: # CP1 = can handle claims challenges (CAE) capabilities = None if "AZURE_IDENTITY_DISABLE_CP1" in os.environ else [ "CP1" ] self._client_applications[tenant_id] = PublicClientApplication( client_id=self._auth_record.client_id, authority="https://{}/{}".format(self._auth_record.authority, tenant_id), token_cache=self._cache, http_client=self._client, client_capabilities=capabilities) return self._client_applications[tenant_id]
def access_account(token): if not token: return "" else: ''' tenantid and appid are Azure AD internal data, it is internal information, do not leave it exposed in the code, it is here to use as an example I advise to have it recorded in a safe.''' appid = "your_app_id" tenantid = "yout_tenant_id" ''' The username and password encoding was used base64 but you can use one of your own.''' auth_decode = base64.b64decode(token).decode() username, password = auth_decode.split(":") if appid and tenantid: ''' O scopo você define dentro do Azure AD. ''' scope = ["User.ReadBasic.All"] app = PublicClientApplication( appid, authority="https://login.microsoftonline.com/" + tenantid) result = None accounts = app.get_accounts(username=username) if accounts: logging.info( "Account(s) exists in cache, probably with token too. Let's try." ) result = app.acquire_token_silent(scope, account=accounts[0]) if not result: logging.info( "No suitable token exists in cache. Let's get a new one from AAD." ) result = app.acquire_token_by_username_password(username, password, scopes=scope) ''' If the validation is successful it returns the token, otherwise it prints the errors found. ''' if "access_token" in result: return result else: print(result.get("error")) print(result.get("error_description")) print(result.get("correlation_id")) if 65001 in result.get("error_codes", []): print("Visit this to consent:", app.get_authorization_request_url(scope)) return "" else: return ""
def CLIENT_AUTH(self) -> PublicClientApplication: """ Azure auth provider (client) Uses the Microsoft Authentication Library (MSAL) for Python to simplify requesting access tokens from Azure. This is used for the client/editor component of this application, which is considered a 'public' client as this application runs on the user's device, and therefore isn't confidential. Note: The Flask Azure OAuth provider is used for the server/catalogue component, instantiated in the application factor method. :rtype PublicClientApplication :return: Microsoft Authentication Library Public Client application """ return PublicClientApplication(client_id=self.AUTH_CLIENT_ID, authority=self.AUTH_CLIENT_TENANCY)
def getConfidentialClientAccessToken(self) -> Optional[str]: # Initialise the app if not already exist if not self.app: logging.info("Initialise msal connection app") self.app = ConfidentialClientApplication( client_id=self.app_id, authority=self.authority, client_credential=self.app_secret) # try to get the token from cache if already exist result = self.app.acquire_token_silent(scopes=self.scopes, account=None) if not result: logging.info( "No suitable token exists in cache. Let's get a new one from AAD." ) result = self.app.acquire_token_for_client(scopes=self.scopes) if "access_token" in result: return result["access_token"] return None
def get_access_token(self): '''Get access token from cache or request new''' cache = SerializableTokenCache() if os.path.exists('token_cache.bin'): cache.deserialize(open('token_cache.bin', 'r').read()) if cache.has_state_changed: atexit.register( lambda: open('token_cache.bin', 'w').write(cache.serialize())) app = PublicClientApplication(self.CLIENT_ID, authority=self.AUTHORITY, token_cache=cache) token_response = None accounts = app.get_accounts() if accounts: print("Pick the account you want to use to proceed:") for index, account in enumerate(accounts): print(index, account["username"]) account_nr = int(input("Type number: ")) chosen = accounts[account_nr] token_response = app.acquire_token_silent(["Notes.Read"], account=chosen) if not token_response: print('Trying to get token...') flow = app.initiate_device_flow(scopes=["Notes.Read"]) print(flow['message']) if 'enter the code ' in flow['message']: auth_code = flow['message'].split( 'enter the code ')[1].split()[0] pyperclip.copy(auth_code) print(f'Code {auth_code} has been copied to clipboard.') token_response = app.acquire_token_by_device_flow(flow) if "access_token" in token_response: return token_response["access_token"] else: print(token_response.get("error")) print(token_response.get("error_description")) print(token_response.get("correlation_id"))
from msal import PublicClientApplication import requests import uuid import json client_id = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX' # Or App Id from Portal Azure client_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' directory_id = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX' # Also known as: tenant authority = 'https://login.microsoftonline.com/' + directory_id username = '******' # Office365/Outlook Email account result = None graph_endpoint = 'https://graph.microsoft.com/v1.0{0}' app = PublicClientApplication(client_id, client_credential=None, authority=authority) # We now check the cache to see # whether we already have some accounts that the end user already used to sign in before. accounts = app.get_accounts() if accounts: result = app.acquire_token_silent(config["scope"], account=username) if not result: # So no suitable token exists in cache. Let's get a new one from AAD. flow = app.initiate_device_flow(scopes=["User.Read", "Calendars.Read"]) print(flow) result = app.acquire_token_by_device_flow(flow) if "access_token" in result: print(result["access_token"]) # Yay!
class AADClient(object): """ This object uses the Microsoft Authentication Library for Python (MSAL) to log in and authenticate users using AAD. The only public method is get_access_token(), which returns an access token if one already exists in the cache, else it will fill the cache by prompting the user to log in. """ def __init__(self, url: str): self._base_url = url self.cache = BonsaiTokenCache() atexit.register(write_cache_to_file, self.cache) retry_count = 1 while True: try: self._app = PublicClientApplication(_AAD_CLIENT_ID, authority=_AAD_AUTHORITY, token_cache=self.cache) if self._app: break except ConnectionError as e: log.info('ConnectionError on attempt {} to ' 'create msal PublicClientApplication, ' 'retrying...'.format(retry_count)) if retry_count >= 5: raise e retry_count += 1 def _log_in_with_device_code(self) -> dict: """ Recommended login method. The user must open a browser to https://microsoft.com/devicelogin and enter a unique device code to begin authentication. """ flow = self._app.initiate_device_flow(_AAD_SCOPE) print(flow["message"]) sys.stdout.flush() # needed to print on Windows return self._app.acquire_token_by_device_flow(flow) def _log_in_with_password(self) -> dict: """ This login method is less secure and should be used for automation only. """ return self._app.acquire_token_by_username_password( os.environ['BONSAI_AAD_USER'], os.environ['BONSAI_AAD_PASSWORD'], _AAD_SCOPE) def _get_access_token_from_cache(self): """ This also does a token refresh if the access token has expired. """ result = None accounts = self._app.get_accounts() if accounts: """ Bonsai config only gives us the short username, and token cache stores accounts by email address (e.g. soc-auto vs [email protected]). So, if there are multiple accounts, assume the first one for now. """ chosen = accounts[0] result = self._app.acquire_token_silent(_AAD_SCOPE, account=chosen) return result def get_access_token(self): # attempt to get token from cache token = self._get_access_token_from_cache() if token: return 'Bearer {}'.format(token['access_token']) # no token found in cache, user must sign in and try again if (use_password_auth()): self._log_in_with_password() else: print('No access token found in cache, please sign in.') self._log_in_with_device_code() token = self._get_access_token_from_cache() if token: return "Bearer {}".format(token['access_token']) message = 'Error: could not fetch AAD access token after login.' raise AuthenticationError(message) def get_workspace(self): # make sure we have access token to request workspace auth_token = self.get_access_token() # get workspace, store to cache and return helper = AADRequestHelper(self._base_url, auth_token) self.workspace = helper.get_workspace() return self.workspace
class AADClient(object): """ This object uses the Microsoft Authentication Library for Python (MSAL) to log in and authenticate users using AAD. The only public method is get_access_token(), which returns an access token if one already exists in the cache, else it will fill the cache by prompting the user to log in. """ def __init__(self, tenant_id: Optional[str] = None): # cache file should be written to home directory home = os.path.expanduser('~') if home: self._cache_file = os.path.join(home, '.bonsaicache') else: raise RuntimeError('Unable to find home directory.') self.cache = TokenCache(self._cache_file) retry_count = 1 effective_tenant_id = tenant_id if tenant_id is not None and tenant_id != 'None' else 'organizations' _AAD_AUTHORITY = 'https://login.microsoftonline.com/' + effective_tenant_id while True: try: self._app = PublicClientApplication(_AAD_CLIENT_ID, authority=_AAD_AUTHORITY, token_cache=self.cache) if self._app: break except ConnectionError as e: log.info('ConnectionError on attempt {} to ' 'create msal PublicClientApplication, ' 'retrying...'.format(retry_count)) if retry_count >= 5: raise e retry_count += 1 def _log_in_with_device_code(self) -> Dict[str, str]: """ Recommended login method. The user must open a browser to https://microsoft.com/devicelogin and enter a unique device code to begin authentication. """ flow = self._app.initiate_device_flow(_AAD_SCOPE) print(flow["message"]) sys.stdout.flush() # needed to print on Windows return self._app.acquire_token_by_device_flow(flow) def _log_in_with_password(self) -> Dict[str, str]: """ This login method is less secure and should be used for automation only. """ return self._app.acquire_token_by_username_password( os.environ['BONSAI_AAD_USER'], os.environ['BONSAI_AAD_PASSWORD'], _AAD_SCOPE) def _get_access_token_from_cache(self): """ This also does a token refresh if the access token has expired. """ result = None accounts = self._app.get_accounts() if accounts: """ Bonsai config only gives us the short username, and token cache stores accounts by email address (e.g. soc-auto vs [email protected]). So, if there are multiple accounts, assume the first one for now. """ chosen = accounts[0] result = self._app.acquire_token_silent(_AAD_SCOPE, account=chosen) return result def get_access_token(self): # attempt to get token from cache token = self._get_access_token_from_cache() if token: return 'Bearer {}'.format(token['access_token']) # no token found in cache, user must sign in and try again if use_password_auth(): self._log_in_with_password() else: print('No access token found in cache, please sign in.') self._log_in_with_device_code() token = self._get_access_token_from_cache() if token: return "Bearer {}".format(token['access_token']) message = 'Error: could not fetch AAD access token after login.' raise AuthenticationError(message)
def _init_impl(self): self._msal_client = PublicClientApplication( client_id=self._cloud_info.kusto_client_app_id, authority=self._cloud_info.authority_uri(self._auth), proxies=self._proxy_dict)
def _init_impl(self): self._msal_client = PublicClientApplication(client_id=self._cloud_info.kusto_client_app_id, authority=self._auth)