Last active
February 28, 2025 12:01
-
-
Save atodev/6bc23783b1e1764fab4e6ba8d48a2acd to your computer and use it in GitHub Desktop.
[MSGRAPH]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import requests | |
| from OpenSSL import crypto | |
| # Set base URL for Microsoft Graph API | |
| BASE_URL = "https://login.microsoftonline.com" | |
| # Set API endpoint for token | |
| ENDPOINT = "/{tenant_id}/oauth2/v2.0/token" | |
| # Set tenant ID | |
| TENANT_ID = "tenant_id_here" | |
| # Set client ID | |
| CLIENT_ID = "client_id_here" | |
| # Set certificate path | |
| CERT_PATH = "certificate.pem" | |
| # Set certificate password | |
| CERT_PASS = "password_here" | |
| # Set scopes | |
| SCOPES = "https://graph.microsoft.com/.default" | |
| # Load certificate | |
| cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(CERT_PATH, "rb").read()) | |
| # Get certificate thumbprint | |
| thumbprint = cert.digest("sha1").decode("utf-8").replace(":", "").upper() | |
| # Set URL for token endpoint | |
| url = BASE_URL + ENDPOINT.format(tenant_id=TENANT_ID) | |
| # Set request data | |
| data = { | |
| "client_id": CLIENT_ID, | |
| "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", | |
| "client_assertion": thumbprint, | |
| "grant_type": "client_credentials", | |
| "scope": SCOPES | |
| } | |
| # Send request to API | |
| response = requests.post(url, data=data) | |
| # Check if request was successful | |
| if response.status_code == 200: | |
| # Get access token from response | |
| access_token = response.json()["access_token"] | |
| # Print access token | |
| print(access_token) | |
| else: | |
| # Print error message if request was not successful | |
| print(f"Error: {response.json()['error_description']}") | |
| ------------------------------------------------------------------------------- | |
| In this example, we are using the /{tenant_id}/oauth2/v2.0/token endpoint to retrieve an access token from the Microsoft Graph API. The tenant ID, client ID, and certificate path are set in the corresponding variables. The certificate is loaded and the thumbprint is calculated and used as the client assertion in the request. The request is sent to the API and the response is checked for success. If the request was successful, the access token is extracted from the response and printed. If the request was not successful, an error message is printed. | |
| --- with cache | |
| import json | |
| import requests | |
| from cryptography.hazmat.backends import default_backend | |
| from cryptography.x509 import load_pem_x509_certificate | |
| from cryptography.hazmat.primitives import serialization | |
| # Set tenant ID, client ID, and resource URL | |
| TENANT_ID = "tenant_id_here" | |
| CLIENT_ID = "client_id_here" | |
| RESOURCE = "https://graph.microsoft.com" | |
| # Set path to certificate file and password | |
| CERT_FILE = "certificate.pem" | |
| CERT_PASS = "certificate_password_here" | |
| # Set cache file name and expiration time | |
| CACHE_FILE = "token_cache.json" | |
| EXPIRATION_TIME = 3600 # 1 hour in seconds | |
| # Load certificate | |
| with open(CERT_FILE, "rb") as f: | |
| cert_data = f.read() | |
| cert = load_pem_x509_certificate(cert_data, default_backend()) | |
| # Get certificate thumbprint | |
| thumbprint = cert.fingerprint(hashes.SHA1()).hex() | |
| # Get certificate public key | |
| public_key = cert.public_key() | |
| pem = public_key.public_bytes( | |
| encoding=serialization.Encoding.PEM, | |
| format=serialization.PublicFormat.SubjectPublicKeyInfo | |
| ) | |
| # Set request URL | |
| url = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/token" | |
| # Set request headers and payload | |
| headers = { | |
| "Content-Type": "application/x-www-form-urlencoded" | |
| } | |
| payload = { | |
| "grant_type": "client_credentials", | |
| "client_id": CLIENT_ID, | |
| "client_secret": pem.decode("utf-8"), | |
| "resource": RESOURCE | |
| } | |
| # Check if cache file exists | |
| try: | |
| # Load cache file | |
| with open(CACHE_FILE, "r") as f: | |
| cache = json.load(f) | |
| # Check if cache is still valid | |
| if cache["expires_on"] > time.time(): | |
| # Use cached token if it is still valid | |
| token = cache["access_token"] | |
| else: | |
| # Request new token if cache has expired | |
| response = requests.post(url, headers=headers, data=payload) | |
| # Check if request was successful | |
| if response.status_code == 200: | |
| # Get token from response | |
| token = response.json()["access_token"] | |
| # Save token to cache file | |
| with open(CACHE_FILE, "w") as f: | |
| json.dump({ | |
| "access_token": token, | |
| "expires_on": time.time() + EXPIRATION_TIME | |
| }, f) | |
| else: | |
| # Print error message if request was not successful | |
| print(f"Error: {response.json()['error_description']}") | |
| except FileNotFoundError: | |
| # Request new token if cache file does not exist | |
| response = requests.post(url, headers= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- powershell with msal | |
| https://blogs.aaddevsup.xyz/2020/07/using-msal-net-to-perform-the-client-credentials-flow-with-a-certificate-instead-of-a-client-secret-in-a-netcore-console-appliction/ | |
| with Postman | |
| https://blogs.aaddevsup.xyz/2020/10/how-to-use-postman-to-perform-a-client-credentials-grant-flow-with-a-certificate/ | |
| $cert=New-SelfSignedCertificate -Subject "CN=DaemonConsoleCert" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature | |
| create the cert | |
| https://www.youtube.com/watch?v=Q620JbCsq1I | |
| https://github.com/erik-de-bont/debontonline/blob/main/azure/msgraphapi/part_3/Create-SelfSignedCertificate.ps1 | |
| with python | |
| https://github.com/mattfeltonma/python-msal-cert-authentication-demo | |
| https://blogs.aaddevsup.xyz/2020/07/using-msal-net-to-perform-the-client-credentials-flow-with-a-certificate-instead-of-a-client-secret-in-a-netcore-console-appliction/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import requests | |
| def auth_o365(): | |
| # Auth call | |
| req_token_body = { | |
| "grant_type": "client_credentials", | |
| "client_id": client_id, | |
| "client_secret": client_secret, | |
| "scope": "https://graph.microsoft.com/.default", | |
| } | |
| response = requests.post( | |
| "https://login.microsoftonline.com/{}/oauth2/v2.0/token".format(tenant_name), | |
| json=req_token_body, | |
| ) | |
| return response.json() | |
| def read_calendar(token): | |
| # Loop all users | |
| api = "https://graph.microsoft.com/v1.0/users" | |
| users = requests.get( | |
| api, | |
| headers={ | |
| "Authorization": "Bearer {}".format(token["access_token"]), | |
| "Content-Type": "application/json", | |
| }, | |
| ).json() | |
| for u in users["value"]: | |
| # All events for user | |
| # upn = '[email protected]' | |
| upn = u["value"][0]["userPrincipalName"] | |
| # upn = users["value"][0]["userPrincipalName"] # changed to user | |
| api = ( | |
| "https://graph.microsoft.com/v1.0/users/{}/events" | |
| "?$top=999" | |
| "&$filter=start/dateTime ge '2022-01-01' and end/dateTime le '2022-11-17'" | |
| ).format(upn) | |
| print(api) | |
| events = requests.get( | |
| api, | |
| headers={ | |
| "Authorization": "Bearer {}".format(token["access_token"]), | |
| "Content-Type": "application/json", | |
| }, | |
| ).json() | |
| while True: | |
| for r in events["value"]: | |
| # Properties | |
| event_id = r["id"] | |
| subject = r["subject"] | |
| body_preview = r["bodyPreview"] | |
| start = r["start"]["dateTime"] | |
| end = r["end"]["dateTime"] | |
| attendees_count = len(r["attendees"]) | |
| organizer_name = r["organizer"]["emailAddress"]["name"] | |
| organizer_address = r["organizer"]["emailAddress"]["address"] | |
| print("EVENT: Start={} End={} Id={}".format(start, end, event_id)) | |
| if "@odata.nextLink" in events: | |
| events = requests.get( | |
| events["@odata.nextLink"], | |
| headers={ | |
| "Authorization": "Bearer {}".format(token["access_token"]), | |
| "Content-Type": "application/json", | |
| }, | |
| ).json() | |
| else: | |
| break | |
| def main(): | |
| token = auth_o365() | |
| print(token) | |
| read_calendar(token) | |
| main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| https://oofhours.com/2020/09/05/using-microsoft-graph-from-python/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| https://medium.com/@marian.reha/query-ms-graph-api-in-python-e8e04490b04e |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Import the required modules | |
| import requests | |
| import json | |
| # Set the base URL for the Microsoft Graph API | |
| base_url = 'https://graph.microsoft.com/v1.0/' | |
| # Set the URL for the desired endpoint, including any query parameters | |
| endpoint_url = base_url + 'me/messages?$top=100' | |
| # Set the authorization headers | |
| auth_headers = { | |
| 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', | |
| 'Content-Type': 'application/json' | |
| } | |
| # Set a flag to track whether there are more pages of results | |
| more_pages = True | |
| # Set a counter to track the number of pages processed | |
| page_count = 0 | |
| # Set an empty list to store the results | |
| results = [] | |
| while more_pages: | |
| # Make the GET request | |
| response = requests.get(endpoint_url, headers=auth_headers) | |
| # Convert the response to JSON | |
| data = response.json() | |
| # Check for errors | |
| if 'error' in data: | |
| print(f'Error: {data["error"]["message"]}') | |
| break | |
| # Add the items from the current page to the results list | |
| results += data['value'] | |
| # Check if there is a 'nextLink' in the response | |
| if '@odata.nextLink' in data: | |
| # If there is, update the URL for the next request | |
| endpoint_url = data['@odata.nextLink'] | |
| else: | |
| # If there is not, set the flag to False to stop the loop | |
| more_pages = False | |
| # Increment the page counter | |
| page_count += 1 | |
| # Print a status update | |
| print(f'Processed page {page_count}') | |
| # Print the number of items in the results list | |
| print(f'Number of items: {len(results)}') | |
| This code will make requests to the specified Microsoft Graph API endpoint, using the $top query parameter to specify the number of items to include in each page of results. It will then continue to make requests and append the results to the results list until there are no more pages of results, indicated by the absence of a @odata.nextLink in the response. | |
| https://chat.openai.com/chat |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import requests | |
| import json | |
| Set the base URL for the Microsoft Graph API | |
| base_url = "https://graph.microsoft.com" | |
| Set the endpoint for the user's messages | |
| endpoint = "/v1.0/me/messages" | |
| Set the access token | |
| access_token = "<YOUR_ACCESS_TOKEN>" | |
| Set the initial URL for the pagination loop | |
| url = base_url + endpoint | |
| Set a flag to indicate whether there are more pages of data | |
| more_pages = True | |
| Set a counter to keep track of the number of pages | |
| page_count = 0 | |
| Set a limit on the number of pages to retrieve | |
| page_limit = 10 | |
| Set the request headers | |
| headers = { | |
| "Authorization": "Bearer " + access_token, | |
| "Content-Type": "application/json" | |
| } | |
| Set the request parameters | |
| params = { | |
| "top": 100, # Set the number of records per page | |
| "select": "subject,receivedDateTime" # Set the properties to retrieve | |
| } | |
| Start the pagination loop | |
| while more_pages and page_count < page_limit: | |
| # Make the GET request | |
| response = requests.get(url, headers=headers, params=params) | |
| ------------------------------------------------------------------- | |
| # Check for a successful response | |
| if response.status_code == 200: | |
| # Increment the page counter | |
| page_count += 1 | |
| # Get the data from the response | |
| data = response.json() | |
| # Loop through the messages in the page | |
| for message in data["value"]: | |
| # Print the message details | |
| print("Subject:", message["subject"]) | |
| print("Received:", message["receivedDateTime"]) | |
| print() | |
| # Check if there is a next page of data | |
| if "nextLink" in data: | |
| # Set the URL for the next page | |
| url = data["nextLink"] | |
| else: | |
| # Set the flag to indicate there are no more pages | |
| more_pages = False | |
| else: | |
| # Print the error message | |
| print("Error:", response.text) | |
| break |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import requests | |
| # Set base URL for Microsoft Graph API | |
| BASE_URL = "https://graph.microsoft.com" | |
| # Set API endpoint for paginated results | |
| ENDPOINT = "/v1.0/me/messages" | |
| # Set API access token | |
| TOKEN = "access_token_here" | |
| # Set initial URL for paginated results | |
| url = BASE_URL + ENDPOINT | |
| # Set initial page and page size | |
| page = 0 | |
| page_size = 100 | |
| # Set initial list for messages | |
| messages = [] | |
| # Set flag to check if more pages exist | |
| has_more_pages = True | |
| while has_more_pages: | |
| # Set URL parameters for pagination | |
| params = { | |
| "$top": page_size, | |
| "$skip": page * page_size | |
| } | |
| # Set request headers | |
| headers = { | |
| "Authorization": f"Bearer {TOKEN}" | |
| } | |
| # Send request to API | |
| response = requests.get(url, params=params, headers=headers) | |
| # Check if request was successful | |
| if response.status_code == 200: | |
| # Get messages from response | |
| response_messages = response.json()["value"] | |
| # Append messages to list | |
| messages += response_messages | |
| # Check if more pages exist | |
| if "@odata.nextLink" in response.json(): | |
| # Set URL for next page | |
| url = response.json()["@odata.nextLink"] | |
| # Increment page number | |
| page += 1 | |
| else: | |
| # Set flag to False if no more pages exist | |
| has_more_pages = False | |
| else: | |
| # Set flag to False if request was not successful | |
| has_more_pages = False | |
| # Print final list of messages | |
| print(messages) | |
| ------------------------------------------------- | |
| In this example, we are paginating through the results of the /v1.0/me/messages endpoint to retrieve a list of messages. The $top and $skip URL parameters are used to control the page size and the starting index of each page of results. The @odata.nextLink property in the response is checked to determine if there are more pages of results to retrieve. If there are, the URL for the next page is set and the page number is incremented. If there are no more pages, the loop is exited. The final list of messages is printed at the end. | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-create-self-signed-certificate | |
| ##$certname = "{certificateName}" ## Replace {certificateName} | |
| $certname = "test" | |
| $cert = New-SelfSignedCertificate -Subject "CN=$certname" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256 | |
| Export-Certificate -Cert $cert -FilePath "D:\Pfizer\Code\$certname.cer" | |
| https://www.youtube.com/watch?v=7Bkv9J9mVr0 | |
| PowerShell script to create self signed certificate. | |
| $FilePath = 'C:\Users\Dipes\Desktop\certificates\abc' | |
| $StoreLocation = 'CurrentUser' # be aware that LocalMachine requires elevated privileges | |
| $expirationYears = 1 | |
| $SubjectName = $tenant_id + '.' + $client_id | |
| $cert_password = $client_id | |
| $pfxFileName = $SubjectName + '.pfx' | |
| $cerFileName = $SubjectName + '.cer' | |
| $PfxFilePath = $FilePath + $pfxFileName | |
| $CerFilePath = $FilePath + $cerFileName | |
| $CertBeginDate = Get-Date | |
| $CertExpiryDate = $CertBeginDate.AddYears($expirationYears) | |
| $SecStringPw= ConvertTo-SecureString -String $cert_password -Force -AsPlainText | |
| $Cert = New-elfSignedCertificate -DnsName $SubjectName -CertStoreLocation "cert:\$StoreLocation\My" -NotBefore $CertBeginDate -NotAfter $CertExpiryDate -KeySpec Signature | |
| Export-PfxCetificate -cert $Cert -FilePath $PFXFilePath -Password $SecStringPw | |
| Export-Certificate -cert $Cert -FilePath $CerFilePath | |
| Connect Microsoft Graph | |
| Connect-MgGraph -ClientID YOUR_APP_ID -TenantId YOUR_TENANT_ID -CertificateThumbprint "" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| https://blog.darrenjrobinson.com/microsoft-graph-using-msal-with-python-and-certificate-authentication/ | |
| --god one | |
| https://www.youtube.com/watch?v=Q620JbCsq1I | |
| and | |
| https://www.youtube.com/watch?v=KWKiwpK-L5o |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment