ROPC (Resource Owner Password Credentials Grant) Flow No ratings yet.

0

Overview

This blog post is intended for the Exchange Administrators that are using Powershell scripts to consume the Outlook REST API v1.0 endpoint //outlook.office365.com/api/v1.0 authenticating with user credentials.

With the REST API v1.0 with support to Basic Authentication deprecation, a transition is required to the Microsoft Graph API or to the REST API v2.0 EndPoint.

One way to acquire a token to consume restful services without user interaction is using the ROPC flow. The Resource Owner Password Credentials grant type is suitable in cases where the resource owner has a trust relationship with the client, such as the device operating system or a highly privileged application.

How it works

Azure Active Directory (Azure AD) supports the resource owner password credential (ROPC) grant which allows an application to sign in the user by directly handling their password. The ROPC flow requires a high degree of trust and user exposure and developers should only use this flow when the other, more secure, flows can’t be used.

Important

  • The Azure AD v2.0 endpoint only supports ROPC for Azure AD tenants, not personal accounts. This means that you must use a tenant-specific endpoint (//login.microsoftonline.com/{tenantId_or_name}) or the organizations endpoint.
  • Personal accounts that are invited to an Azure AD tenant can’t use ROPC.
  • Accounts that don’t have passwords can’t sign in through ROPC. For this scenario, we recommend that you use a different flow for your app instead.
  • If users need to use multi-factor authentication (MFA) to log in to the application, they will be blocked instead.

Protocol Diagram

Example

Get a message collection from the entire mailbox of the signed-in user with Powershell and REST v2.0

Create an app registration

1. In the Azure Portal click on Azure Active Directory in the navigation menu on the left then click on App registrations then click on New application registration on the right

2. Fill in the Name and the Sign-on URL fields and click Create

3. Click on Settings

4. On the Settings page click on Required permissions

5. On the Required permissions page click Add

6. On the Add API access page click Select an API

7. On the Select an API page select Office 365 Exchange Online and click Select

8. On the Enable Access page, click the checkboxes for the appropriate access then click Select

9. Create a new Client Secret for the application, on the Settings page click on Keys

To generate a new Key (client secret) type in a Description, select the validity period in the Expires column and click Save

10. Make a copy of the key value as you won’t be able to retrieve it if you navigate away from this page

* Application Permissions: Your client application needs to access the web API directly as itself (no user context). This type of permission requires administrator consent and is also not available for native client applications.

** Delegated Permissions: Your client application needs to access the web API as the signed-in user, but with access limited by the selected permission. This type of permission can be granted by a user unless the permission requires administrator consent.

The Powershell Script

Acquiring an Access Token

$client_id = [System.Web.HttpUtility]::UrlEncode("<<<< client id >>>>")
$client_secret = [System.Web.HttpUtility]::UrlEncode("<<<< client secret >>>>")
$tenant = [System.Web.HttpUtility]::UrlEncode("<<<< tenant >>>>")
$user = [System.Web.HttpUtility]::UrlEncode("<<<< user >>>>")
$password = [System.Web.HttpUtility]::UrlEncode("<<<< password >>>>")
$mailbox = [System.Web.HttpUtility]::UrlEncode("<<<< mailbox >>>>")
$AuthUri = "https://login.microsoftonline.com/" + $tenant + "/oauth2/v2.0/token"
$AuthBody =
"grant_type=password" + "&" +
"client_id=$client_id" + "&" +
"client_secret=" + $client_secret + "&" +
"username=" + $user + "&" +
"scope=" + [System.Web.HttpUtility]::UrlEncode("https://outlook.office.com/mail.read") + "%20offline_access" + "&" +
"password=" + $password
$Authorization =
Invoke-RestMethod -Method Post -ContentType application/x-www-form-urlencoded
-Uri $AuthUri `
-Body $AuthBody

Where:

  • The AuthUri is the OAuth v2.0 token endpoint
  • The grant type must be password for the ROPC flow
  • The client id is the newly created application id
  • The client secret is the key created in our web application
  • The scope is as defined in the API access.
  • The user and password are the credentials of the user to consume the API

IMPORTANT: We do not recommend storing credentials encrypted. The script above is for illustration purposes only. 

Query the REST API using the access token

$requestHeaders = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
For optimal performance when using the new Outlook REST endpoint,
add an x-AnchorMailbox header for every request and set it to the user's email address.
$requestHeaders.Add('X-AnchorMailbox', $mailbox)
Each message in the response contains multiple properties, including the Body property.
The message body can be either text or HTML.
If the body is HTML, by default, any potentially unsafe HTML (for example, JavaScript) embedded in the Body property would be removed
before the body content is returned in a REST response.
To get the entire, original HTML content, include the following HTTP request header
$requestHeaders.Add('Prefer', 'outlook.allow-unsafe-html')
$requestHeaders.Add('Authorization', "Bearer " + $Authorization.access_token)
Get messages
You can get a message collection or an individual message from a mailbox folder.
#
Each message in the response contains multiple properties, including the Body property.
The message body can be either text or HTML. If the body is HTML, by default,
any potentially unsafe HTML (for example, JavaScript) embedded in the Body property would be removed before the body content is returned in a REST response.
#
https://docs.microsoft.com/en-us/previous-versions/office/office-365-api/api/version-2.0/mail-rest-operations#GetMessages
$requestUri = "https://outlook.office.com/api/v2.0/users/" + $mailbox + "/messages"
$request =
Invoke-RestMethod -Headers $requestHeaders ` -Uri $requestUri ` -Method Get
$request.value

Attachments

Download the PowerShell script here

References

Change Log

DateAuthorTypeDescription
2019-01-02Pedro Tomás e SilvaOriginal 

0

Please rate this

Leave a Reply

Your email address will not be published. Required fields are marked *