I'm making a Java application to send Mail as any user in a Microsoft tenant, with Graph APIs, so I'm using the client credentials flow (no login, automatic send). I've registered an app in Azure AD giving the following application permissions (not delegated), checking out the admin consent for every item:
- Mail.Send
- Mail.ReadWrite
- User.Read.All
For semplicity, I've tried also with calls in Postman, but I have the same issue as in the Java app. I take for granted that I have got a valid access token (If I try with an invalid one, I get a 401: Unauthorized
). The following is the decoded access token that I get from https://jwt.ms/, with all the scopes included:
...
"roles": [
"Mail.ReadWrite",
"User.Read.All",
"Mail.Send"
],
...
This is my code in Java:
String user = "/users/<my user id or my user principal name>";
UserRequestBuilder defaultUser = new UserRequestBuilder(graphClient.getServiceRoot() + user, graphClient, null);
//graphClient.me()
defaultUser
.sendMail(UserSendMailParameterSet
.newBuilder()
.withMessage(message)
.withSaveToSentItems(saveToSentItems)
.build())
.buildRequest()
.post();
I can't use the "me" target (me()
method) because this is client credentials flow, so there isn't a logged user. I need to specify the sender in this way: /users/{id | userPrincipalName}/sendMail
.
This is how the call in Postman is composed:
Method: POST
URL:
- .https://graph.microsoft.com/v1.0/users/
{my user id or my user principal name}
/sendMail
AUTHORIZATION:
- Bearer Token (my access token)
HEADERS:
- Content-Type: application/json
BODY(JSON):
{
"recipient": <recipient email>,
"subject": "This is a test mail",
"from": <mail that created the tenant, app and access token>,
"text": "This is the messge body..."
}
That's the response from the server (in both Postman and Java app):
STATUS: 405: Method Not Allowed
BODY:
{
"error": {
"code": "Request_BadRequest",
"message": "Specified HTTP method is not allowed for the request target.",
"innerError": {
"date": "2022-08-05T07:17:34",
"request-id": "XXXXXXXX-6075-4d13-83ed-XXXXXXXXXXXX",
"client-request-id": "XXXXXXXX-6075-4d13-83ed-XXXXXXXXXXXX"
}
}
}
Note 1:
I got my user id and my user principal name also with a Postman call using my access token,
exploiting the User.Read.All
permission, with the following call:
https://graph.microsoft.com/v1.0/users
That's the response:
...
"userPrincipalName": "XXXXXX_XXXXXX.XXX#EXT#@sendClientCredMail.onmicrosoft.com",
"id": "XXXXXXXX-4457-4944-bb22-XXXXXXXXXXXX"
}
]
}
Note 2: Note that if I use the "principal name" in the call, I get a 405, if I use the "id" instead I get a 404: Not Found
Thanks in advance for any help, I've been trying for hours!