Skip to main content

Command Palette

Search for a command to run...

APEX & Office 365 Integration - Introduction

Updated
8 min read
APEX & Office 365 Integration - Introduction
J
Hi, thanks for stopping by! I am focused on designing and building innovative solutions using AI, the Oracle Database, Oracle APEX, and Oracle REST Data Services (ORDS). I hope you enjoy my blog.

Introduction

This blog post is the first in a series covering integrations between Oracle APEX and Microsoft Office 365. These integrations are made possible using Microsoft Graph APIs. Being able to integrate with Office 365 opens up a world of possibilities. In upcoming posts, I will cover integrating APEX with the following Office 365 Services:

  • Calendars
  • Sharepoint
  • Email

There are many other Office 365 services that you can integrate with, including:

  • Users and Groups
  • Contacts
  • Application registrations
  • Notes
  • To Do

This first post will cover background information and configurations that underpin the remaining ones. These include MS Active Directory configurations, testing the MS Graph API calls with Postman, and creating APEX Web Credentials.

This post assumes you have administrator access to Microsoft Azure for your Office 365 Tenant.

Azure AD App registration

Before we can start accessing Office 365 services, you need to create an App registration using Azure Active Directory. App registrations control permissions for which MS Graph APIs we have access and generate credentials we can use for authentication and authorization.

❗In the below configuration, we will assign the 'Directory.Read.All' permission. This configuration gives us access to fetch a list of users from our Office 365 tenancy. We will utilize different permissions in subsequent posts.

  • Login to the Microsoft Entra Admin Center
  • 🧭 Azure Active Directory > Applications > App registrations Microsoft App registrations
  • Click '+ New registration' Register Application Step 1
  • Enter a name for the application and click 'Register' Register Application Step 2
  • ✏️ Note the Application (client) ID and the Directory (tenant) ID
  • Click on API Permissions, then click '+ Add permission'
  • Click 'Microsoft Graph' Register Application Step 3
  • Search for 'Directory.Read.All', select it and click 'Add permissions' Register Application Step 4
  • Navigate to 'Certificates & secrets' then click '+New client secret' Register Application Step 5
  • Enter a name, select an expiration period and then click 'Add' Register Application Step 6
  • ✏️ Note of the Secret Value (not the Secret ID)
  • 📅 Note the Expires date; you will need to create a new credential before this one expires
  • The final step is to Grant Admin consent for the App registration to access the 'Directory.Read.All' permission on behalf of the Tenant. Click the 'API permissions' menu option, then click 'Grant admin consent for XXXX' where 'XXXX' is your tenant name Register Application Step 7
  • You should now see a green check next to the permission Register Application Step 8

Top Tip: Use the MS Graph List Applications API to get the expiration dates for client secrets. Combine this with an APEX Automation and send an email ten days before secrets expire.

Securing AD App registrations

At this point, we should recognize that the App registration we just created can list all users in the entire organization. This may be OK for users, but having an App registration with credentials that allow it to read (or write) anyone's email or calendar would not be good.

The good news is you can limit access to specific users (or groups) using Exchange online access policies. This document provides additional details. Note: You need a free Azure Portal Subscription before you can apply access policies.

Unfortunately, access policies only apply to the following MS Graph API Permissions:

  • Mail.Read, Mail.ReadBasic, Mail.ReadBasic.All, Mail.ReadWrite, Mail.Send
  • MailboxSettings.Read, MailboxSettings.ReadWrite
  • Calendars.Read, Calendars.ReadWrite
  • Contacts.Read, Contacts.ReadWrite

An access policy applies to all of the above permissions assigned to a given App registration. Unfortunately, they don't help with other services like Users, SharePoint and OneDrive.

Example Access Policy

This section will cover the basics of creating an access policy. Again, access policies only cover specific permissions (see list above), so this will not impact the users API that I am demoing in this post. They will come in handy when we get to the calendar and email integrations. The following steps assume you have an Azure Portal Subscription setup.

  • Login To: https://admin.microsoft.com/AdminPortal/Home
  • Start Powershell (click the highlighted icon in the navigation bar). Note: You will need to provision Azure storage to run Powershell. The cost is pennies per week Start_PowerShell.png
  • Once the PowerShell session has started, run the following command: connect-exopssession Start_PowerShell_2.png
  • Run the following command to verify you have access to Create Policies:

Get-ManagementRole -Cmdlet New-ApplicationAccessPolicy

  • You should see the following:
PS /home/jonathan> Get-ManagementRole -Cmdlet New-ApplicationAccessPolicy
Name                       RoleType
----                       --------
Organization Configuration OrganizationConfiguration
  • Run the command to create the policy:

New-ApplicationAccessPolicy -AccessRight RestrictAccess -AppId "e5920b6c-r43f-4314-5dc5-a9d4182d3435" -PolicyScopeGroupId jon.dixon@cloudnueva.com -Description "Restrict access to jon.dixon"

  • The value for AppId is the Application (client) ID on the 'App registration'
  • The value for PolicyScopeGroupId is the user id or the userPrincipalName of the user you want to restrict access to
  • In the above example, I am limiting the App registration e5920b6c-r43f-4314-5dc5-a9d4182d3435 to only be able to access email or calendars for jon.dixon@cloudnueva.com
  • See here for additional parameters available for New-ApplicationAccessPolicy

You should see something like this when you run the New-ApplicationAccessPolicy command:

RunspaceId       : cae4b4e5-fea9-4b7e-b13f-f2bc500b450f
ScopeName        : Jonathan Dixon
ScopeIdentity    : jon.dixon
Identity         : 990876cd-77d9-4fab-8cd2-57020376ed11\e5920b6c-r43f-4314-5dc5-a9d4182d3435:S-1-5-21-4112488020-863137326-2000415224-44886207;fd205ba6-0a65-4c53-8b2b-e0a185ea624e
AppId            : e5920b6c-r43f-4314-5dc5-a9d4182d3435
ScopeIdentityRaw : S-1-5-21-4112488020-863137326-2000415224-44886207;fd205ba6-0a65-4c53-8b2b-e0a185ea624e
Description      : Restrict access to jon.dixon
AccessRight      : RestrictAccess
ShardType        : All
IsValid          : True
ObjectState      : Unchanged
  • Finally, run the following command to check the policy was created OK: Get-ApplicationAccessPolicy Start_PowerShell_3.png

❗It can take up to an hour for the policy to take effect on the Graph APIs. Once the policy has taken effect (remember it could be an hour later), you will get the below error if you try and access a mailbox that does not conform to the policy: Error_Accessing_Secured_Mailbox.png

Testing with Postman

Now that we have credentials that can access Office 365 users, we can test them using Postman (or a similar tool).

MS Graph API Access Token

The first thing we need to do is get an access token. We can use the access token to run the MS Graph APIs.

Setup a POST request just like the following screenshot: Postman Screenshot Get Token

  • Request Type: POST
  • URL = https://login.microsoftonline.com/<Directory (tenant) ID>/oauth2/v2.0/token, where <Directory (tenant) ID> is the Directory (tenant) ID from the App registration
  • Body Type = x-www-form-urlencoded
  • Body > grant_type = client_credentials
  • Body > client_id = Application (client) ID from the App registration
  • Body > client_secret = Secret Value from the App registration
  • Body > scope = https://graph.microsoft.com/.default

You should get a 200 OK response when you call the API. The access_token in the JSON response is a JSON Web Token (JWT). If interested, you can decode the JWT by going to https://jwt.ms/ and pasting the token value. Screenshot Decoded Access Token Note the app_displayname field and roles array in the below excerpt from the decoded JWT.

{
  "app_displayname": "MS Graph Blog Application",
  "roles": [
    "Directory.Read.All"
  ]

MS Graph Users API

Now that we have an access token with permissions to run the Users API, we can test it with Postman. Setup Postman as follows: Postman Screenshot Get Users MS Graph API

  • Request Type: GET
  • URL = https://graph.microsoft.com/v1.0/users
  • Authorization Type: Bearer
  • Token = The access_token obtained from the token API above

Oracle APEX Web Credential

The final step in this post is to create APEX Web Credentials, which we can use to Authenticate from APEX.

Create the APEX Web Credential

  • Login to APEX Builder
  • 🧭 Application Builder > Workspace Utilities > Web Credentials > Click 'Create'
  • Enter the details below:
    • Authentication Type = OAuth2 Client Credentials
    • OAuth Scope = https://graph.microsoft.com/.default
    • Client ID or Username = Application (client) ID from the App registration
    • Client Secret or Password & Verify Client Secret or Password = Secret Value from the App registration Create Oracle APEX Web Credentials
  • Click 'Create'

Test the APEX Web Credential

Let's test we can access the users API by creating a REST Data Source.

  • Login to APEX Builder
  • 🧭 Application Builder > Application > Shared Components > REST Data Source
  • Click 'Create' > Select 'From scratch' > Click 'Next'
  • Enter the Name and URL Endpoint as shown in the below screenshot Create APEX Rest Data Source Step 1
  • Click 'Next' twice without changing any values
  • Enter the authentication details as shown in the below screenshot. Note: The 'OAuth Token URL' is the same URL you used in the Postman Access Token request above Create APEX Rest Data Source Step 2
  • Click 'Create REST Source Manually'
    • Note: Unfortunately, if you click 'Discover' at this point, you will get an Authentication error, so you have to complete the setup manually
  • Edit the newly created REST Source, then click the 'Edit Data Profile' button
  • We are testing our configuration, so we will only configure three columns. Change the three default columns as follows. Note that 'Row Selector' must be changed to value. When complete, click 'Apply Changes' Create APEX Rest Data Source Step 3
  • Click the Play icon in the 'Test Operation' column Create APEX Rest Data Source Step 4.png
  • You should see something like the following if everything is working: Create APEX Rest Data Source Step 5.png

Conclusion

We have successfully configured an Active Directory App registration, an APEX Web Credential, and run a test call to the Users MS Graph API. These are the fundamental steps to interacting with any Microsoft Office 365 service. I promise the remaining posts in this series will be much more fun!

🔗 Read More

Comments (10)

Join the discussion
V

Hi Jon, I get this error Bad Request HTTP Status Code: 400 Request ID: ce4b9b11684bc90f6f5a5eb6a8f4fd5a

Request Timestamp: 2024-02-12T17:55:08.352429Z

I have followed the steps exactly as you describe, what could I be missing? In postman it works correctly.

Thank you very much for your answer.

N

I'm getting ORA-29024: Certificate validation failure, right after clicking "next" in the first screen of create REST data source.

J
Jon Dixon2y ago

Hi, You will need to import the SSL certificate into a database wallet and reference that wallet from APEX. See this post for details https://blogs.oracle.com/apex/post/apex-https-certificates-and-the-oracle-wallet

N

Thank you! Working on that.Jon Dixon

N

Hi, everything worked exactly as you described, every single step, however the last step (restful test operation button) says: "Found no data while parsing the service response". Any help please? Nehemias Arias

N

Hi, Disregard last comment/question. Everything working perfectly. Thank you!!! Moving to next article now. Nehemias Arias

1
D

How do I handle pagination?

J
Jon Dixon3y ago

Hi Jordan, You must write a REST Source Plugin for pagination using REST Data Sources https://blogs.oracle.com/apex/post/apex-181-early-adopter-2-rest-services-and-plug-ins. I haven't gotten my head around how to do that yet, so currently, I use PL/SQL to fetch data in a loop. I either use a PL/SQL pipelined table function or add data to an APEX Collection.

S

Just what I needed

1
P

Hi Jon, I just stumbled over your post.

We were working on an MS Graph SDK for PL/SQL some time ago and put it on GitHub, could be interesting for you.

J
Jon Dixon3y ago

Very cool; I'll check it out.

I

Hi Jon,

Thank you.

Didn't you have to set up ACL rules and wallet to make the test work?

J
Jon Dixon3y ago

Ordinarily, yes but I run my stuff on Oracle Cloud Free Tier which already has ACLs and a Wallet with the most common certificates already installed.

1
J

Jon Dixon Hola Jhon Tengo mi cuenta en Oracle Cloud, con una instancia limpia, en la cual Instale Oracle 21c Expres y APEX 23.2, pero no me permite integrarme para autenticarme con Azure AD ni tampoco me deja enviar correos a través de mi servicio de correo de Office 365, voy días intentando e intentando, pero no me sale.

Me solicita habilitar ACL y Wallet, donde puedo encontrar como configurar esto.

V

Hi Jon,

I am getting

{"error":{"code":"InvalidAuthenticationToken","message":"Access token validation failure. Invalid audience.",

error when calling users API. Followed same steps. Please help

J
Jon Dixon3y ago

Hi, It is hard to say from the information provided, but it could be that you did not grant admin consent after assigning the permission. Check the part of the Blog that starts with "The final step is to Grant Admin consent for the App...".

G

I noticed in your list 365 apps you didn’t mention WORD. Is this because we can’t use any available APIs for WORD or no one thinks there’s a need for that. We currently considering the new AOP add on. We aren’t using Office with that. Thanks.

J
Jon Dixon3y ago

Hi, the MS Graph APIs only cover Office 365 services, like email, calendar, SharePoint, etc. They do not cover Office 365 products like Word, Excel, PowerPoint, etc. If you need to generate Word or Excel Documents, then I would recommend APEX Office Print.

S
sssuarez3y ago

Thank you Jon. Just to confirm, if I do not set up the access policies as you outline above, the app registration credentials will automatically allow the viewing of users' emails and calendars?

Thanks again.

S
sssuarez3y ago

Just seems like this is not applying the principle of 'least privileges' for access.

J
Jon Dixon3y ago

You are correct. Without the access policy the *.All roles provide access to all users email, calendar, etc. unfortunately access policies only work for email and calendar currently

L

Awesome as always Jon!

1
J
Jon Dixon3y ago

Cheers, Louis. Glad you enjoyed it.