Authorization and access tokens¶
Commands provided with the Office 365 CLI manipulate different settings of Office 365. Before you can execute any of the commands in the CLI, you have to log in to the Office 365 service corresponding to your command, such as SharePoint or Microsoft Graph.
- the URL of the service to which you are logged in and the URL of the API you're communicating with are the same, eg. you're connected to AAD Graph at
https://graph.windows.netand you're calling
https://graph.windows.net/myorganization/servicePrincipalsor you're connected to SharePoint tenant admin site at
https://contoso-admin.sharepoint.comand you're calling the tenant admin API at
- you want to renew the refresh token persisted in the Office 365 CLI
- the URL of the service to which you are logged in and the URL of the API you're calling are different, eg. you're connected to a SharePoint Online tenant admin site at
https://contoso-admin.sharepoint.com, but you're calling
https://contoso.sharepoint.com/sites/team/_api/web/tenantappcatalog/AvailableApps/GetById('cd807889-9107-416e-88e4-7575789ab35c')/installto install an app on a regular SharePoint site
- you're obtaining access token for a service different than the one to which you are logged in and don't want to break the existing connection
Authorization in the Office 365 CLI¶
There are a number of ways in which you can authenticate and authorize with Office 365. The Office 365 CLI uses the OAuth protocol to authorize with Office 365 and its services. OAuth flows in Office 365 are facilitated by Azure Active Directory.
Azure AD application used by the Office 365 CLI¶
Office 365 CLI gets access to Office 365 through a custom Azure AD application named PnP Office 365 Management Shell. If you don't want to consent this application in your tenant, you can use a different application instead.
When you decide to use your own Azure AD application, you need to choose the application to be a public client. Despite the setting's description, the application will not be publicly accessible. This setting enables the use of the device flow for your own application. Without activating this setting, it is not possible to complete the authentication process. The option is currently only available in the preview blade for managing for Azure AD applications.
When specifying a custom Azure AD application to be used by the Office 365 CLI, you can either choose to use one application for all Office 365 services or a separate application for each service. To use one Azure AD application for all Office 365 CLI commands, set the
OFFICE365CLI_AADAPPID environment variable to the ID of your Azure AD application. If you want to use a different Azure AD application for each Office 365 service use the following environment variables:
OFFICE365CLI_AADAADAPPID- for the ID of the Azure AD application to communicate with Azure AD Graph
OFFICE365CLI_AADAZMGMTAPPID- for the ID of the Azure AD application to communicate with the Azure Management Service
OFFICE365CLI_AADGRAPHAPPID- for the ID of the Azure AD application to communicate with the Microsoft Graph
OFFICE365CLI_AADSPOAPPID- for the ID of the Azure AD application to communicate with SharePoint Online
Office 365 CLI requires the following permissions to Office 365 services:
- Office 365 SharePoint Online (Microsoft.SharePoint)
- Have full control of all site collections
- Read user profiles
- Read and write managed metadata
- Microsoft Graph
- Invite guest users to the organization
- Read and write all groups
- Read and write directory data
- Access directory as the signed in user
- Read and write identity providers
- Send mail as a user
- Read and write to all app catalogs
- Windows Azure Active Directory
- Access the directory as the signed-in user
- Windows Azure Service Management API
- Access Azure Service Management as organization users
After changing the ID of the Azure AD application used by the Office 365 CLI refresh the existing connections to Office 365 using the corresponding
<service> login command. If you try to use the existing connection, Office 365 CLI will fail when trying to refresh the existing access token.
Access and refresh tokens in the Office 365 CLI¶
After completing the OAuth flow, the CLI receives from Azure Active Directory a refresh- and an access token. Each web request to Office 365 APIs contains the access token which authorizes the Office 365 CLI to execute the particular operation. When the access token expires, the CLI uses the refresh token to obtain a new access token. When the refresh token expires, the user has to reauthenticate to Office 365 to obtain a new refresh token.
Services and commands¶
Each command in the Office 365 CLI belongs to a service, for example the spo site add command, which creates a new modern site, belongs to the SharePoint Online service, while the aad sp get command, which lists Azure Active Directory service principals, belongs to the Azure Active Directory Graph service. Each service in Office 365 is a different Azure Active Directory authorization resource and requires a separate access token. When working with the CLI, you can be simultaneously connected to multiple services. Each command in the CLI knows which Office 365 service it communicates with and for which resource it should have a valid access token.
Communicating with Office 365¶
Before a command can log in to Office 365, it requires a valid access token. Office 365 CLI offers you two methods to obtain a valid access token: Auth.ensureAccessToken and Auth.getAccessToken. While the methods seem similar, they work differently and are meant for different purposes.
Refresh access token for the current resource¶
If you're building a command that operates on the same URL, as the service to which the user is connected, you should use the
Auth.ensureAccessToken method to refresh the token. Not only does this method resolve to a valid access token, which you can use directly in your code, but also stores the new access- and refresh token in the
auth.service object from which you can use in any point in code.
For example: you're building a command that retrieves the list of service principals from the Azure Active Directory (aad sp get). The command uses the Azure Active Directory Graph API (
https://graph.windows.net) for this. Since the resource URL of the AAD Graph service (
https://graph.windows.net) and the URL of the API that the command has to call (
https://graph.windows.net/myorganization/servicePrincipals) are both located on the same domain
https://graph.windows.net, you should call the
Auth.ensureAccessToken method to obtain a valid access token for the AAD Graph service, before calling the API.
As another example, let's take a method that communicates with the SharePoint Online tenant admin API to set a tenant property (spo storageentity set). While using the spo login command, users can log in to any SharePoint site, the spo storageentity set command requires the user to be connected to the SharePoint tenant admin site. As a result, both the URL of the service, to which the user is connected (
https://contoso-admin.sharepoint.com) and the URL of the API used by the service (
https://contoso-admin.sharepoint.com/_vti_bin/client.svc/ProcessQuery) are located on the same domain
https://contoso-admin.sharepoint.com, which is why you should call the
Auth.ensureAccessToken method to obtain a valid access for the SharePoint Online tenant admin site, before calling the API.
Obtain a valid access token for a different resource¶
In some cases, while the user is connected to one service (with a corresponding resource), you need to retrieve a valid access token for a different resource. This is often the case when building SharePoint commands. In Office 365, SharePoint resources are spread over the following different domains:
contoso-admin.sharepoint.com - which hosts the SharePoint Online tenant admin site,
contoso.sharepoint.com - which hosts regular SharePoint sites and
contoso-my.sharepoint.com - which hosts users' OneDrive sites. From Azure Active Directory point of view, all these domains are perceived as separate resources and require different access tokens.
If you're building a command that allows users to specify a URL on which the operation should be performed, such as spo app install, you cannot make any assumptions of the service to which they're connected, and you should obtain a valid access token for the resources corresponding to the URL specified by the user, using the
Auth.getResourceToken method. While the
Auth.getResourceToken method also returns a valid access token for the specified resource, it doesn't update the connection information on the
Why two different methods to get tokens¶
In the Office 365 CLI, logging in to Office 365 services is interactive and requires user input. If commands relied on context information from the site, to which users are logged in, it would be impossible to build scripts using the Office 365 CLI commands.
Some SharePoint commands require to be executed in the context of the tenant admin site. Some commands additionally require specifying tenant information. For performance reasons, this information is retrieved only initially, when logging in to SharePoint, if the specified site to log in to is a tenant admin site. Because tenant information doesn't change, there is no point in retrieving it on every call to SharePoint. If users would first log in to a regular SharePoint site, and would then switch to the tenant admin site, the tenant information would be missing and the commands requiring it would fail.
Rules of thumb¶
- if you're building a command for a service other than SharePoint Online, you will most likely use the
- if the command you're building allows the user to specify a URL on which the API is called, you should use the
Auth.getAccessTokenmethod to get access token for the URL specified by the user