In this post we need to get a token that can be used for Microsoft Teams / Graph API so we can interact with resources in O365. It should be noted that this token, once you have it, can be used to login to the Teams PowerShell module. You need two tokens to use the Access Token method, you need a Graph API Token and a Teams PowerShell Token.
What is a Teams PowerShell Token?
I have no clue if that is the correct wording, but the idea is that when you run this command:
Connect-MicrosoftTeams -AccessTokens @($graphToken, $teamsToken)
You need a Teams Token that has the audience of 48ac35b8-9aa8-4d74-927d-1f4a14a0b239. This relates to the Application found in Microsoft Azure. The other token is a standard Microsoft Graph Token.
Create Application in Azure
You need to login to the Microsoft Azure Portal. You will go to Azure Active Directory | App Registrations and choose New Registration.
Please note the Web and http://localhost at the bottom for the redirect URL. That is needed to make this work. Once you have created your application, we need to setup permissions.
Go to the API Permissions and click Add a permission. On the resulting page, select APIs my organization uses and search for Skype.
You are going to select the top option, Skype and Teams Tenant Admin API. Notice the Application (client) ID listed. It matches the audience type we needed above. On the next page, you are going to select Delegated Permissions and choose user_impersonation.
NOTE: I have tried everything under the sun to make Application Permissions work here – it doesn’t. When you login to the Teams PowerShell Module, you need two tokens – Graph and Teams. They both must come from the same user!
Click Add Permission at the bottom of the page. Your API Permissions should now look like this.
Next, we need to Grant admin consent. You can click the Grant admin consent for (tenant) name. The last step we need to do is go to Certificates and Secrets and create a client secret. Select a new client secret and set the time to a length that you like. Once you get your client secret, it will be shown ONLY ONCE, so make sure you copy it down.
At this point in time, you should have:
- Tenant ID (found on overview tab)
- Client ID (found on overview tab)
- Client Secret (created on certificates & secret tab)
What if Multi-Tenant?
If in the first step, you set up the application as multi-tenant because another domain will also use this application. Maybe you are using MSAL for authentication? There are a lot of odd-ball scenarios that could play out here. Someone from that other domain would need to consent, at an admin level, to the permissions. If you were to open a browser and go to:
https://login.microsoftonline.com/yourtenantID/adminconsent?client_id=yourclientsecret
You would be displayed a page to consent to the permissions.
Again, this is ONLY NEEDED if you don’t have the ability to consent on behalf of your organization or if you were using a multi-tenant login experience.
Get Your Token
Now you need to get your token from this application and Microsoft. Remember, our goal is to use Microsoft Teams PowerShell module, so we need both a Graph and Teams Token. For fun, I’ve decided that I’m going to use Power Automate to get these tokens. Why? Because Power Automate is COOL! But honestly, you can do this via Insomnia or another Rest Client.
NOTE: I have a Power Automate premium subscription that allows me to do this. One of the reasons I like to do it this way is that I can store all the valuable items in an Azure Key Vault.
I’m going to create a few things in Power Automate, if you just want to skip to the end, feel free. Yes, I’m adding a layer of complexity, but I’m doing it for the name of security (and coolness).
First, we are going to create a Key Vault in Azure. Navigate to Key Vaults in the Azure Portal and choose create.
All we really need to do is give it a name. Select Review & Create now. After a moment, we need to add some Secrets to the Key Vault. Head to the Secrets tab and select Generate/Import. Here you will manually enter your secrets. We need to do this twice, once for the users’ password and a second time for the client secret.
You should have two secrets like this:
Once we have added both of our secrets, let’s head over to Power Automate and create a flow that will automatically create both of our tokens for us. Again, you don’t need to do this in Power Automate, I think it’s just fun to show how things connect to each other.
Create Flow
We start by creating a manual flow. We are going to pick Manually trigger a flow. Then we are going to add three variables: TenantId, ClientId and Username.
Next, we are going to add Get Secret via the Azure Key Vault. When you add the step of Azure Key Vault it should ask you for your Key Vault name. Two tips here: First, whomever is creating the Power Automate flow MUST have Get Secret permissions in the Azure Key Vault. That is found under Access Policies in the Azure Portal.
Second tip. Under Data | Connections is where the connector to Azure Key Vault exists. If you have any issues, that is where you can set the Key Vault name.
We are going to next add the Get Secret and then the Initialize Variable steps to our flow. It should look a lot like this:
We are going to repeat this for the UserPassword next.
NOTE: For both Get Secret actions from KeyVault, we want to make sure we don’t log the information into Power Automate. So make sure to choose settings and set Secure Inputs and Secure Outputs
When everything is done, we should have all of our variables setup and secured. Your variable list should look like this.
Get Your Tokens (For Real!)
We have finally made it to the part you cared about at the very beginning. How do we get the tokens? We are going to add a HTTP Post action to our flow. It will have these permissions we need for the Teams Token.
Teams Token
The HTTP method | POST |
The request URL | https://login.microsoftonline.com/your tenant id/oauth2/token |
The Content-Type header | application/x-www-form-urlencoded |
The request body | grant_type=password&resource=48ac35b8-9aa8-4d74-927d-1f4a14a0b239&client_id=your client id&username=your username&password=your password&client_secret=client secret&scope=48ac35b8-9aa8-4d74-927d-1f4a14a0b239/user_impersonation |
In the request body make sure to note. We are using the resource of 48ac35b8-9aa8-4d74-927d-1f4a14a0b239 and then the score is 48ac35b8-9aa8-4d74-927d-1f4a14a0b239/user_impersonation. This is an absolute MUST!
Graph Token
The HTTP method | POST |
The request URL | https://login.microsoftonline.com/your tenant id/oauth2/token |
The Content-Type header | application/x-www-form-urlencoded |
The request body | grant_type=password&resource=https://graph.microsoft.com&client_id=your client id&username=your username&password=your password&client_secret=client secret |
If we look at our flow, it should look a lot like this.
We are going to hit save and then the Test Button. We are going to Manually trigger the flow. And then choose Run Now.
When it is done, you should see everything green and happy.
If you expand out the Teams Token and view at the results, you will see an access_token. Go ahead and copy that. And then you can repeat and graph your graph token now as well.
If you want, you can head over to https://jwt.ms and load your Teams Token into the JWT decoder. The key element, the audience (aud) is that GUID from the start.
Now we want to use this in PowerShell, so go ahead and run this command. Obviously, replace your tokens.
$graphToken = ‘GRAPH_TOKEN’;
$teamsToken = ‘TEAMS_TOKEN’;
Connect-MicrosoftTeams -AccessTokens @($graphToken, $teamsToken);
And there you have it!
1 COMMENTS