Nov 13 2018 05:01 PM
Nov 13 2018 05:01 PM
Hi,
I'm attempting to programatically send email using PowerShell and the Office 365 outlook REST API (can't use SMTP as it's blocked).
I've managed to set up my Web App in Azure AD with what I'm pretty sure are the requisite permissions and have authorized those via the adminconsent URI. I've set up the shared secret and can successfully retrieve an access token using the client credentials flow, but when I attempt to use that token to send mail I get a 401 unauthorized error.
Here's my code with all the juicy bits replaced
Nov 13 2018 10:37 PM
Nov 13 2018 11:40 PM
Do check the token for the scope/permissions, you can parse it on jwt.ms/jwt.io or via PowerShell as well if needed.
Nov 14 2018 02:59 AM
As I stated at the beginning of the post - I can't use SMTP as it is blocked
Nov 14 2018 09:38 AM - edited Nov 14 2018 09:40 AM
Nov 14 2018 09:38 AM - edited Nov 14 2018 09:40 AM
So after a bit more reading I've discovered that you can't use a client credentials flow using a shared secret to send mail, you have to use a client credentials flow using certificates! Wish that ere documented better.
So I created a self-signed cert, uploaded it against the web app in Azure AD and updated the manifest to include the cert details. Then I tried rolling my own JWT and trying to sign it with RS256 to no avail. After more digging it's apparent that your self signed cert has to be created using the right provider or it won't be able to be used to sign RSA - only HMAC! - So switched from makecert to powershell to create the new cert - re-uploaded the public cert and re-updated the manifest on the app, then gave up on all the work I'd done earlier on JWT stuff and fell back on .NET ADAL modules.
After all that I can successfully obtain an authentication token using client credential flow and certificates - and analysing the JWT I get back I can see I have permissions to Send.Mail, but now when I try and use that token I'm getting a 403 Forbidden error!!
Who knew it could be so hard to send an email!!
Anyone have any idea what else I can try?
Thanks,
Mark.
Nov 15 2018 03:29 AM
Nov 15 2018 03:29 AM
SolutionOK, I've figured out the issue - putting this here for others to find if they hit the same problem.
The underlying issue is that the O365 v2.0 Web API is woefully under-documented!
The main issue with using the Client Credentialworflow is that it authenticates the App itself, and not a user, therefore you need to specify the user to send the email from in the URI - but I had to guess that from the v1.0 API!
Changing the URI used with the access token from ;
https://outlook.office365.com/api/v2.0/me/sendmail
to
https://outlook.office365.com/api/v2.0/users/<user spn>/sendmail
Then the API knows which user the email is being sent from and the token which has the 'Send mail for any user' claim is accepted and the email is sent.
Hope others find this useful.
Regards,
Mark.
Nov 15 2018 03:29 AM
Nov 15 2018 03:29 AM
SolutionOK, I've figured out the issue - putting this here for others to find if they hit the same problem.
The underlying issue is that the O365 v2.0 Web API is woefully under-documented!
The main issue with using the Client Credentialworflow is that it authenticates the App itself, and not a user, therefore you need to specify the user to send the email from in the URI - but I had to guess that from the v1.0 API!
Changing the URI used with the access token from ;
https://outlook.office365.com/api/v2.0/me/sendmail
to
https://outlook.office365.com/api/v2.0/users/<user spn>/sendmail
Then the API knows which user the email is being sent from and the token which has the 'Send mail for any user' claim is accepted and the email is sent.
Hope others find this useful.
Regards,
Mark.