How to configure Hybrid mode for Exchange 2016 to have OAuth2 Client Credentials flow working with Microsoft Graph API - oauth-2.0

I configured Hybrid mode on a customer's Exchange 2016. Now users' mailboxes are exposed on the Microsoft Graph API using the individual consent flow (authorization code Oauth2 flow).
Getting an admin consent with a client credentials flow seems to work : a token is retreived on the Microsoft endpoint, the payload is correct (right scopes), but it triggers an "unknown error" when using it to get a mailbox content through the Microsoft Graph API. The same token does work to get directory information (meaning the token is valid at some point).
Is Hybrid mode compatible with the Client Credentials flow ? Is there any parameters to configure in Exchange to enable this flow ?

I stumbled upon the same issue some time ago. Just let it slide, as I thought it was some wrong configuration on the Exchange side.
If you inspect both tokens you'll see that the sid is missing on the Client Credentials token, I think exchange needs some sort of on-premise user id inside the token to work. I'm not sure if this flow is supported since I cannot find anything about this topic on their documentation websites.
I just found a totally related question, check out https://stackoverflow.com/a/56108226/639153 for a complete answer.
The issue is actually somewhere else - Exchange doesn't seem to support client_credentials flow. You can, however force it via following PowerShell (make sure to restart your IIS after applying):
$apps = Get-PartnerApplication
# Microsoft Graph is 2nd item in the array, if you are unsure, list the items by calling $apps first
$apps[1] | Set-PartnerApplication -AppOnlyPermissions $apps[1].ActAsPermissions
The full explanation can be found here: https://blog.thenetw.org/2019/05/13/using-client_credentials-with-microsoft-graph-in-hybrid-exchange-setup/

Related

How to configure an app in azure portal for multiple email addresses, from the same O365 tenant, to use OAuth with SMTP without user interaction?

We use in our company email addresses for each employee and for 3 departments (service, support and reports) - for example <employee_name>#<company_name>.de or support#<company_name>.de ("<..._name>" is just a placholder for posting here). Our programs use PHPMailer for sending Emails from the 3 departments via SMTP without user interaction (Host: smtp.office365.com), that means the PHPMailer is called by programs/scripts that are started by the Microsoft Task Scheduler on a computer where none of our Microsoft-Users is logged in. Now we want to switch from Basic SMTP Auth to Oauth2.
So we registered in the main tenant (<boss_name>#<company_name>.de) in the azure portal a web app "PHPMailer" and received the refresh token with the file "get_oauth_token.php", which is included in PHPMailer. The mail order via OAuth is working now, but only when <boss_name>#<company_name>.de is the username and the email sender (From).
It's not working when both are for example reports#<company_name>.de (prefered way)
SMTP INBOUND: "535 5.7.3 Authentication unsuccessful [AM6PR10CA0036.EURPRD10.PROD.OUTLOOK.COM]"
And it's not working when <boss_name>#<company_name>.de is the username and From is for example reports#<company_name>.de (willy-nilly compromise)
SMTP INBOUND: "554 5.2.252 SendAsDenied; <boss_name>#<company_name>.de not allowed to send as reports#<company_name>.de
We tried to change the configuration for <boss_name>#<company_name>.de ("SendAs" parameter) and of the app in the azure portal (for example defining the department email addresses as owner of the app or adding Mail.Send in the Micrsoft Graph API as application permission) and waited 24 hours (synchronization delay) - but no change.
So i've read in the past weeks countless tutorials from Microsoft, PHPMailer and others, and forums like stackoverflow. But nowhere i could find the necessary information, how to change the configuration.
Examples:
Microsoft
Give mailbox permissions to another Microsoft 365 user - Admin help
Authenticate an IMAP, POP or SMTP connection using OAuth
Get access on behalf of a user
PHPMailer
Using Gmail with XOAUTH2 (unfortunately no explanation for Microsoft)
Basic Usage of the OAuth 2.0 Client from the PHP League
Microsoft Provider for OAuth 2.0 Client Microsoft OAuth 2.0 support for PHPMailer from Steven Maguire
But in this answer to my older question #ADyson wrote that the app just needs the appropriate permissions in the Graph API - so it must be possible. Unfortunately he didn't write, how to set the permissions...
So, how can i achieve my goal?
(Because the PHPMailer is working and i think it's just a configuration problem, i omitted code snippets. If you although need code or more information, please tell me...)
Update:
PHPMailer
Thanks to #greew i found a well made explanation with helpfull screenshots for delegated permissions:
Microsoft Azure and XOAUTH2 setup guide
Unfortunately it doesn't help for my case with application permissions, because it is made for the case, that the Microsoft user is logged in on the compauter where PHPMailer is working.
Not supported?
I found in the Microsoft page Authenticate an IMAP, POP or SMTP connection using OAuth the following hint:
Note As per the current test with SMTP Oauth 2.0 client credential flow with non-interactive sign in is not supported.
Does this mean, that i'm trying it for nothing, because it is not supported???
#biberman
I just tried setting up a new mailer with the correct permissions and also clicking the "Grant admin consent.." button.
This resulted in me being able to both get the refresh token and also send mail without user interaction on my behalf.
Note: I'm using the single tenant option in the App.
After i found in the Microsoft page Authenticate an IMAP, POP or SMTP connection using OAuth the following hint:
Note As per the current test with SMTP Oauth 2.0 client credential flow with non-interactive sign in is not supported.
i asked the same question in the Microsoft Q&A forum. There i received the following answer/comment:
Currently the Client Credentials flow isn't supported with SMTP Auth (it maybe in the future but there isn't a roadmap item that i know of) so you need to grant SendAS permissions to whatever account you trying to send as in the from or switch to using the Graph API eg one example https://katystech.blog/projects/php-graph-mailer that does support the client credentials flow.
I tried to solve the issue by letting the administrator grant the SendAs permission to all necessary mailboxes, but i still get the error SendAsDenied - maybe it doesn't work with modern authentication (OAuth).
At the end i used the graphMailer from the linked katystech.blog, which is a really slim solution compared to the PHPMailer. First i couldn't get it to work, because our administrator refused to grant the necessary Microsoft Graph permission Mail.ReadWrite (he has security concerns). But i changed the code, so that the email is "build" before sending it, instead of building the email step by step on the Microsoft server and then advising the server to send it (like in the original code).
Now the Mail.ReadWrite permission isn't necessary and i can send from different email addresses. To avoid rewriting the whole code, where the PHPMailer is used, i renamed the functions of Katys graphMailer (and adjusted the params), so that they are similar to the PHPMailer and i only need to replace = new PHPMailer( with = new graphMailer(...

Access Microsoft graph resources with an auth0 login

I'm having difficulties finding documentation for auth0 and microsoft graph integration. My end goal is to have a SPA that can login with a microsoft profile to auth0 (connected to azure ad). Then I want my app to get a token for microsoft graph and do some api calls.
As I've understood it so far, auth0 does not allow you to get the access token to different identity providers in a front end application, but rather that they should use a proxy to get this token. My flow therefore is:
I login with a SPA auth0 app (using a microsoft identity)
This is then used to authenticate to a backend server using a api registration in auth0
The backend has its seperate machine-to-machine app in auth0
Backend api uses this seperate app to get access token to auth0 management api
Current user is fetched (based on the logged in user from front end app login) from management api,
Here i find an access token under the azure identity (if I do the same in the front end, the access tokens are omitted)
Token does not work to call graph, I am unsure of where to send it next.
I am aware that the above is probably completely wrong, that's why I am here :)
My questions are:
1) Is it even possible to get an access token for microsoft graph starting from a login to auth0 in the way I want it to. If not, can it be done from a backend?
2) Does anyone have a link that discusses this, ideally with some code samples.
To answer your first question:
1) Is it even possible to get an access token for microsoft graph starting from a login to auth0 in the way I want it to. If not, can it be done from a backend?
I have had the chance to authenticate apps using the microsoft identity library called MSAl whose documentation is found here. It gives a pretty detailed way to authenticate directly from your SPA.
I have also used the microsoft javascript sdk as it comes inbuilt with token caching and refreshing so that I do not need to build that for myself.
In relation to this,
Does anyone have a link that discusses this, ideally with some code samples.
You can find the samples well described in the samples section of the SDK
I hope this helps.

Outlook add-in Rest Api token to get the SharePoint Rest Api Token

I am building a Outlook Add-in using Node JS and it needs get information from SharePoint Online using SharePoint Rest Api because Graph does`t have an option to get the required information.
Question?
I need a SharePoint online auth token to call SP Rest Api which I am getting using OAuth flow (implicit flow) after user enters credentials.
Is there a way to get the SharePoint online auth token using Outlook Rest Api returned by getCallbackTokenAsync() or getUserIdentityTokenAsync() or "getAccessTokenAsync()" method?
if you only need the SharePoint REST API Token (I assume you mean the one with URLs starting with _api/[...]) then your best bet is to get that token from the /_api/contextinfo endpoint for your site. You do not need the Outlook REST API to do so if I understand the question correctly. So you need to craft a POST request to:
http://yourspsite/_api/contextinfo
Headers:
accept: application/json
content-type: application/json
Get the token value from the returned JSON: e.g. jsonResponse.FormDigestValue
The FormDigestValue field contains the value you want.
There ya go, hope this helps.
Cheers,
Razvan
UPDATE regarding NodeJS in Outlook Add-in:
As you correctly pointed out I left out the requirement that the token be obtained from within the Addin itself. This is currently only possible from within SSO addins (preview). See the following link for how to implement it and use getAccessTokenAsync to get an Azure AD V2 token: https://learn.microsoft.com/de-de/office/dev/add-ins/develop/sso-in-office-add-ins
Make sure to have created the AzureAD V2 App beforehand using https://apps.dev.microsoft.com
Give the app the necessary permissions for the operation e.g. Sites.Read.All for reading items in all site collections.
The resource for the token should look like:
https://[yourtenant].sharepointonline.com/
Caveat: To create an SSO Addin you currently need to be part of the Office Insider Program at: https://products.office.com/de-DE/office-insider - signup required.
Finally: Use the token to call the regular SharePoint REST API, it should accept it if you stick to operations within the permissions you set in the Azure App above.

Getting Access Token for Microsoft Graph from asp.net core2 Authentication web app

I have created a new asp.net core 2 web application. I'm using individual user accounts and added my Microsoft account for external authentication. All of this works like expected.
Now I want to use Microsoft Graph to read my .live profile and eventually read my mailbox and things like that.
I created an authentication provider and I'm able to get an access token back but why I try to use the access token, I'm getting an Authorization_IdentityNotFound error although my clientId and secret is correctly entered.
I think it's caused by the fact that I'm not using the proper parameters to request the access token. I think I'm missing the authorization response code that is normally returned when I sign into my .live account.
Does anyone know how to retrieve that response code or has a working example in asp.net core2. The only sample I can find is in .net core 1.1 and things have changed rather drastically since then.
You're confusing a few different systems here.
In order to access Microsoft Graph API you'll need to pass an Access Token in the authorization header of your call. This is used to both provide Microsoft Graph with your identification as well where you're data is stored (you're tenant).
The actual Access Token isn't issued by Microsoft Graph, it is issued by your tenant. For work/school accounts this is the Azure Active Directory tenant where your account lives. For personal account this is the Outlook.com tenant.
Prior to receiving an Access Token, you first retrieve an Authorization Code. This is returned to the redirect_url you passed to login.microsoftonline.com after you've entered your credentials. Your app then takes this Authorization Code and exchanges it for an Access Token that you'll use to call Microsoft Graph.
If you're looking for a authentication library to handle this process, you should use MSAL.NET. You can find instructions for using this library in the microsoft-authentication-library-for-dotnet repository on GitHub.
Once you have a token, you can either call Microsoft Graph directly or you can leverage the Microsoft Graph Client Library for .NET.

Accessing Calendar, Mail and Contacts of an OAuthenticated user

I configured an application on AzureAd to be multi-tenant, I chose to require all the permissions for Windows Azure Active Directory and Office 365 Exchange Online.
I can get a user to grant permissions, get access tokens, refresh them, OAuth works for me. I always used the "common" keyword instead of the tenant ID, because my app is multi-tenant.
Now, I would like to have (CRUD) access to a user's Mail, Contacts and Calendar with this token. Here is my problem: I am completely lost in all the possible API endpoints. Should I use: graph.windows.net, outlook.office365.com, graph.microsoft.com? This page seems to suggest that graph.microsoft.com is the Swiss army knife that would serve my purpose, but somehow I cannot find a doc that allows me to find the info I'm looking for. Plus, it seems under development and maybe too incomplete for what I want.
If I make queries against outlook.office365.com, I've got a 401 error.
If I put my access token in this token analyzer, it seems healthy although the scope field only shows the permissions I set in the AzureAd portal for Windows Azure Active Directory, not Office 365 Exchange Online.
I am kind of lost, any help would be welcome...
You have a choice:
Call the separate service apis - Your problem is that you acquired a token to call AAD, and then tried to use that to call Outlook - you need to make a separate call to acquire a token for outlook.office365.com through ADAL or through the token endpoint directly. The token acquired for AAD Graph can ONLY be used against AAD Graph. Similarly the token acquired for Outlook can ONLY be used against Outlook APIs.
Just to clarify - Azure AD OAuth can protect/secure multiple web APIs, including O365 APIs, Azure AD Graph, Azure Resource Management APIs, your own APIs and the new O365 unified API. In the first access token request, you specify the first resource you want/need to call. It doesn't have to be AAD Graph - i.e. it's not the default AFAIK. Based on what is consented to, you have the ability to request additional access tokens using the (multi-resource) refresh token. Vittorio's blog post which you link to in your comments does a great job explaining this.
Call the O365 unified API (which is in preview) and IS documented. See below. The beauty of the unified API is that you only need to acquire a token to call graph.microsoft.com and ALL the entities on that endpoint are available to you AND more. It removes the siloed nature of #1, and the requirement to get and manage multiple access tokens to call these different API endpoints. However #1 is currently GA, and the unified API is preview only at this time.
For more on #2 please see https://msdn.microsoft.com/en-us/office/office365/howto/office-365-unified-api-overview and search for "unified" in the list of samples here: https://msdn.microsoft.com/en-us/office/office365/howto/starter-projects-and-code-samples
We are working on improving the unified API documentation. If you are making pure REST calls, then I recommend starting out with the API explorer (and try things like https://graph.microsoft.com/beta/me/events and https://graph.microsoft.com/beta/me/messages to get your calendar events and mail messages), OR the API sandbox (which can show you JS code snippets, and allow you to test your own easily enough). As you can see on the REST examples, to access mail and calendar features in the unified APIs, you should be able to swap the service roots from Outlook to the unified API ie - https://outlook.office365.com/v1.0 -> https://graph.microsoft.com/beta. On the JS sample - we will be adding more capabilities here and additional samples.
NOTE: Personal contacts available in outlook.office365.com are not available in the unified API yet.
Hope this helps

Resources