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)
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 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 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_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 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']
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)
#clientID = 'd7bc7bbf-0018-4027-ab2d-5ac283f48806' #clientID = "1b730954-1685-4b74-9bfd-dac224a7b894" #clientID = "1950a258-227b-4e31-a9cf-717495945fc2" clientID = 'b1b71e9b-6abd-45d1-bf61-127e287d6a59' app = PublicClientApplication(clientID, authority=authority) scope = ["https://graph.microsoft.com/.default"] # The pattern to acquire a token looks like this. result = None # First, the code looks up a token from the cache. # Because we're looking for a token for the current app, not for a user, # use None for the account parameter. result = app.acquire_token_by_username_password(username=userName, password=userPassword, scopes=scope) if "access_token" in result: # Call a protected API with the access token. curToken = result["access_token"] print(curToken) endpoint = graphURI + "beta/conditionalAccess/policies" http_headers = { 'Authorization': 'Bearer ' + curToken, 'Accept': 'application/json', 'Content-Type': 'application/json' } data = requests.get(endpoint, headers=http_headers, stream=False).json() print(data)
class MsalConnection(AppConnection): """ Implementation of the Connection class using msal """ def __init__(self, app_id: str, tenant_id: str, app_secret: str = None, username: str = None, password: str = None, resource: str = DEFAULT_RESOURCE, api_ver: str = DEFAULT_API_VER): super().__init__(app_id=app_id, app_secret=app_secret, tenant_id=tenant_id, resource=resource, api_ver=api_ver) self.username = username self.password = password self.scopes = DEFAULT_SCOPES self.app = None def getAccessToken(self) -> Optional[str]: if self.app_secret: return self.getConfidentialClientAccessToken() return self.getPublicAccessToken() 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 getDeviceFlowAccessToken(self): if not self.app: # must have app initialised before calling that method print( "App must be initialised before calling getDeviceFlowAccessToken" ) return None flow = self.app.initiate_device_flow(scopes=self.scopes) print(flow["message"]) print(flow["verification_uri"]) print(flow["user_code"]) return self.app.acquire_token_by_device_flow(flow) def getUsernamePasswordAccessToken(self): if not self.app: # must have app initialised before calling that method print( "App must be initialised before calling getUsernamePasswordAccessToken" ) return None return self.app.acquire_token_by_username_password(self.username, self.password, scopes=self.scopes) 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
doConditionalAccessPolicyTest = False if doConditionalAccessPolicyTest: print("CAP test") # Create a subscription curClientId = appId curClientId = "0a8b87a1-6811-48b2-8647-97de65bd0dc5" print(f"This will use clientID: {curClientId}.") capURL = graphURI + "beta/conditionalAccess/policies" app = PublicClientApplication(curClientId) capScopes = ["https://graph.microsoft.com/.default"] capToken = app.acquire_token_by_username_password(userName, userPassword, capScopes) capHeader = { "Authorization": "Bearer {}".format(capToken), "Content-Type": "application/json" } capResponse = requests.get(capURL, headers=capHeader) capJSON = json.loads(capResponse.content) print( f"Response of Graph 2.0 API query against {capURL} using ClientID {curClientId} : {capResponse.content}" ) doConditionalAccessPolicyTestWithAdminConsentedSP = False if doConditionalAccessPolicyTestWithAdminConsentedSP: curClientId = appId print(