In this third and final part of the “Understanding Microsoft’s OAuth2 Implementation” series, we will be using the application that we have previously created to authenticate to the Microsoft Graph API.
If you have not done so, please read Part 1 and Part 2 before continuing.
Now, let’s start using the Microsoft Graph API using PowerShell Core!
Using PowerShell Core, we need to generate our “Authorization” URL. We can do this using [Get-MSGraphOAuthCode.ps1].
$ClientId = 'a6b6008e-1cd0-42b7-9649-3d4fec3e3748' $redirectURL = 'https://localhost' $scopes = "https://graph.microsoft.com/Mail.Read https://graph.microsoft.com/People.Read https://graph.microsoft.com/User.Read" Get-MSGraphOAuthCode -ClientId $ClientId -RedirectUrl $redirectURL -Scope $scopes
As you can see, we are calling Get-MSGraphOAuthCode and providing our Client ID (Application ID), redirect URL, and our Scopes to the function. In return we will get a encoded URL that we will need to click and authorize our application based on our provided scopes. You should receive output similar to what follows below.
Copy this URL into your browser and authenticate using the appropriate credentials:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=a6b6008e-1cd0-42b7-9649-3d4fec3e3748&response_type=code&redirect_uri=https%3a%2f%2flocalhost&response_mode=query&scope=openid%20profile%20email%20offline_access%20https%3a%2f%2fgraph.microsoft.com%2fMail.Read+https%3a%2f%2fgraph.microsoft.com%2fPeople.Read+https%3a%2f%2fgraph.microsoft.com%2fUser.Read&state=12345"
Once you copy this URL into your browser, you should be redirected to a login page where you will sign in as the user you are wanting to use this application. Once you have logged in, you will be presented with a dialog that you must accept permissions based on the provided scopes:
Once you click “Accept,” your browser will be redirected to your provided redirect URL. Note, the redirect URL you provide to both your application registration and PowerShell function must match explicitly.
When redirected, you should see a URL similar to this in your browser:
https://localhost/?code=OAQABAAIAAACEfexXxjamQb3OeGQ4GugvnGFvbHYFYZni_m3t5tMUiNhTtWKE-VLVBw6ZNHJsZD3c_hrD4O34ShrbtE8HeyOyDLT-l-lEHihr7cH7whdismVsGpUbfq1J5562eeWunMTU83fJ9IT7HfC6bbkAeBdR7GCrHFTcowvc84AeB9QgaC9Jl-rMJ-5yRhfZCCVpIkt1Pgp2E0iy4PJEX4l7lI534PAEr12DYdIYTvOwWnyLcbSKhmib4eTwkNUFuC2_JK-ruhOdZa5hQs_GOcrxHwio5mzholXvTcy6aLIqVjtrxWUM47wqPp5bMHty1_t-YzVvhRNXsojQLzPT8370nOW9I01WRvLh3db2-4rLv96b9IYmQYPKER24bKIkm5XSpEnlmsqL3-SIIDuAFqat0jyeuQo37QYSIgcvsOzDHrhCcl35XSeDv1CiytYPFvHjjl7i0Zi5o5h1QULlyJjUxnl1som6trEpTdjiN4bGSZFgYmXQxFQYFYYlGaPB8XWZzDdhtQozMupeRGxD6zvIv44qMMAg-RwBwuFKi0tW4_c66O8PxEy2P3hVXY16aVKfsO5BU4ef_igvCY8neoeXxJd0-8vOGQGBshf6aKRettNTWiCBHzm64GpNUkDdqUn_yQ7GShRRUDU-BigRnnLmpgYUvZac3xKSPIy4vaUHdVXCkSAA&state=12345&session_state=ecc60fb6-7bfe-4562-8997-bffbcaf6fe8b
Congratulations! You now have an Authorization Code to interact with the Microsoft Graph API. As you can see, your code is contained within the “code” URL parameters:
OAQABAAIAAACEfexXxjamQb3OeGQ4GugvnGFvbHYFYZni_m3t5tMUiNhTtWKE-VLVBw6ZNHJsZD3c_hrD4O34ShrbtE8HeyOyDLT-l-lEHihr7cH7whdismVsGpUbfq1J5562eeWunMTU83fJ9IT7HfC6bbkAeBdR7GCrHFTcowvc84AeB9QgaC9Jl-rMJ-5yRhfZCCVpIkt1Pgp2E0iy4PJEX4l7lI534PAEr12DYdIYTvOwWnyLcbSKhmib4eTwkNUFuC2_JK-ruhOdZa5hQs_GOcrxHwio5mzholXvTcy6aLIqVjtrxWUM47wqPp5bMHty1_t-YzVvhRNXsojQLzPT8370nOW9I01WRvLh3db2-4rLv96b9IYmQYPKER24bKIkm5XSpEnlmsqL3-SIIDuAFqat0jyeuQo37QYSIgcvsOzDHrhCcl35XSeDv1CiytYPFvHjjl7i0Zi5o5h1QULlyJjUxnl1som6trEpTdjiN4bGSZFgYmXQxFQYFYYlGaPB8XWZzDdhtQozMupeRGxD6zvIv44qMMAg-RwBwuFKi0tW4_c66O8PxEy2P3hVXY16aVKfsO5BU4ef_igvCY8neoeXxJd0-8vOGQGBshf6aKRettNTWiCBHzm64GpNUkDdqUn_yQ7GShRRUDU-BigRnnLmpgYUvZac3xKSPIy4vaUHdVXCkSAA
This Authorization Code is only good for 10 minutes, so we will need to either use it to request an Access Token (below), or you will need to reissue this command to get a new Authorization Code.
To get an access and refresh token, you must to provide the following information:
- ClientID (Application ID generated when creating a new application)
- ClientSecret (Generated Password from application registration)
- AuthCode (Authorization Code returned from the Get-MSOAuthCode)
- Scope (Scopes defined during application registration)
- RedirectURL (Redirect URL defined during application registration)
You can use [Request-MSGraphAccessToken.ps1] PowerShell Core function to get a access_token and refresh_token using your Authorization Code from before. Call this function by providing these parameters:
$ClientId = 'a6b6008e-1cd0-42b7-9649-3d4fec3e3748' $ClientSecret = 'ewwgyTWNYK80)@@?rlCC874' $redirectURL = 'https://localhost' $scopes = "https://graph.microsoft.com/Mail.Read https://graph.microsoft.com/People.Read https://graph.microsoft.com/User.Read" $authCode = 'OAQABAAIAAACEfexXxjamQb3OeGQ4GugvnGFvbHYFYZni_m3t5tMUiNhTtWKE-VLVBw6ZNHJsZD3c_hrD4O34ShrbtE8HeyOyDLT-l-lEHihr7cH7whdismVsGpUbfq1J5562eeWunMTU83fJ9IT7HfC6bbkAeBdR7GCrHFTcowvc84AeB9QgaC9Jl-rMJ-5yRhfZCCVpIkt1Pgp2E0iy4PJEX4l7lI534PAEr12DYdIYTvOwWnyLcbSKhmib4eTwkNUFuC2_JK-ruhOdZa5hQs_GOcrxHwio5mzholXvTcy6aLIqVjtrxWUM47wqPp5bMHty1_t-YzVvhRNXsojQLzPT8370nOW9I01WRvLh3db2-4rLv96b9IYmQYPKER24bKIkm5XSpEnlmsqL3-SIIDuAFqat0jyeuQo37QYSIgcvsOzDHrhCcl35XSeDv1CiytYPFvHjjl7i0Zi5o5h1QULlyJjUxnl1som6trEpTdjiN4bGSZFgYmXQxFQYFYYlGaPB8XWZzDdhtQozMupeRGxD6zvIv44qMMAg-RwBwuFKi0tW4_c66O8PxEy2P3hVXY16aVKfsO5BU4ef_igvCY8neoeXxJd0-8vOGQGBshf6aKRettNTWiCBHzm64GpNUkDdqUn_yQ7GShRRUDU-BigRnnLmpgYUvZac3xKSPIy4vaUHdVXCkSAA' Request-MSGraphAccessToken -ClientId $ClientId -ClientSecret $ClientSecret -AuthCode $authCode -RedirectUrl $redirectURL -Scope $scopes
Once you call this function, you will receive a similar output to this screenshot, which contains both an access_token and a refresh_token:
You will need to keep track of both tokens in some manner. Typical implementations around OAuth 2.0 store these tokens along with timestamps in either the Windows Registry or in a configuration file (json). Either way, you need the access_token when making calls to the Microsoft Graph API.
To determine how long your access_token is valid, you will need to convert the expires_in value from seconds to your desired timestamp. An example would be to use the Get-Date CmdLet and adding 3600 seconds to the current time:
(Get-Date).AddSeconds(3600)
Using the two functions above, you can call the following to get access to the Microsoft Graph API People endpoint:
$ClientId = 'a6b6008e-1cd0-42b7-9649-3d4fec3e3748' $ClientSecret = 'ewwgyTWNYK80)@@?rlCC874' $redirectURL = 'https://localhost' $scopes = "https://graph.microsoft.com/Mail.Read https://graph.microsoft.com/People.Read https://graph.microsoft.com/User.Read" $Authorization = Get-MSGraphOAuthCode -ClientId $ClientId -RedirectUrl $redirectURL -Scope $scopes # Get our authorization code from our web browser and set it as the value for our $AuthCode variable $authCode = 'OAQABAAIAAACEfexXxjamQb3OeGQ4Gugvj3p8GWJ3Dfp8zQEOj11gj0nQzme5WBcWRgJR41sxh2h19SpUsZrVmgsUJo8qErEucTbPdlHKSVNH-qD6Qddpn0rj55XmIwYS4Xr5cnmuqn5YHUYQGz-GNb5k6XwsFMvKljzvv4pA5AceDLFKV3OKppO8PBVo0ibbD_DtwMGAszM6vdm5LXrJLUCqaknpUZfQb5RANTFJjt5IYNH1K_fqQ_TWBEKMVSNbSWgJMdWwA9E6BQQZbd0jrIztyavhEJziFyv5ZUyKRft9AqfccE7ZbfJQK4DNcZ-nP_Z8N5LOZxCs-bYP3BuhflpjRHW5P8cjqAQblIN0hYfuPWAeZGcTG9xUexFeWgdzDqkUpmqEM25jY4t7hdGRhfdL6bnkRGPgQocefj1oc-aMtk2f6-t39N1TU24F_NKSMvDk62bOVdhaKQGEgj9BgHcM9-C9GOhCPwd2rbXOne3EOi95ncC7qFfelJlDHahL3VHizcwr3xtl7ChyBBpI0T-WXaZlt82y2T9Nct1_cBC9ltYD4Kyn66I6GV3icrxyl1jX4mD2pE1uf-8adS968NbniH8VIkSgm8O_yh77beQexVamryOJMIybTbK7eaK9giJJEUTK049iie2EpM3EQIylSjcPASq2U6zdj0VJ3SClzo68mPGmKSAA' $Tokens = Request-AccessToken -ClientId $ClientId -ClientSecret $ClientSecret -AuthCode $authCode -RedirectUrl $redirectURL -Scope $scopes # Now we can call the people endpoint on the Graph API $params = @{ Method = 'Get' Method = 'Get' Authorization = "bearer $($Tokens.access_token)" } Uri = 'https://graph.microsoft.com/v1.0/me/people' } # Call the Graph API and loop through each of the returned values and output them ((Invoke-RestMethod @params).value).ForEach({ Write-Output $_ })
That’s it! You have successfully created an application and interacted with the Microsoft Graph API using the Auth Code Grant flow. You registered your application, requested an authorization code, received access_token and refresh_token and queries the Graph API.
The Microsoft OAuth 2.0 implementation can seem daunting at first, but once you understand the nuances and jargon, it is actually fairly straight-forward. I hope this article has helped you get a better understanding of OAuth2, especially Microsoft’s implementation when interacting with Azure resources.
Continue the conversation
SecOps Hub is a community of security pros gathered to discuss SecOps strategies, incident response best practices and ways to simplify SecOps with security orchestration, automation and response (SOAR). Continue this conversation and jump in on conversations like this one today!