Microsoft OAuth 2.0 Authentication Failure - token_url Bad Request Error - azure

I want to ensure that my OAuth 2.0 authentication credentials. So, I have client_id, client_secret, tenant_id, scope, token_url and auth_url. I am using third party app in order to send a email but, I get error in OAuth 2.0 part as Bad Request Error for token_url.
In this case, when grant_type='client_credentials', how can I fix token_url domains or subdomains?
-> token_url like that https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/token
If you are dominate the this subject, Could you please mention about OAuth 2.0 process?
I tried to changed grant_type parameter as client_credentials. Default was 'refresh_token'.
In this case, it returned like that error:
(530, b'5.7.57 Client not authenticated to send mail. Error: 535 5.7.3 Authentication unsuccessful [ZR2P278CA0041.CHEP278.PROD.OUTLOOK.COM 2023-02-14T08:10:26.343Z 08DB0DEF6EA5D39B]', 'myemail#myemail.com')
2023-02-14 11:10:26,378 INFO [decorators] [send_email] StatusMessage: An error occurred while sending the email: (530, b'5.7.57 Client not authenticated to send mail. Error: 535 5.7.3 Authentication unsuccessful [ZR2P278CA0041.CHEP278.PROD.OUTLOOK.COM 2023-02-14T08:10:26.343Z 08DB0DEF6EA5D39B]', 'myemail#myemail.com')
2023-02-14 11:10:26,379 INFO [decorators] [send_email] StatusMessage: Done with sending email...
So, what is the main problem in this case?
Thank you for your attention,

I tried to reproduce the same in my environment and got the results as below: 
I created an Azure AD Application and granted admin consent to Mail.Send API permission:
  
Based on your requirement you can make use of Client Credential Flow or Authorization Code Flow.
If you want user interaction then make use of Authorization Code Flow.
If you want to send mail as Application then make use of Client Credential Flow. 
I generated the access token via Client Credential Flow by using parameters like below:
https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
client_id:ClientID
client_secret:ClientSecret
scope:https://graph.microsoft.com/.default
grant_type:client_credentials
 
 To send the mail, I used below query:
https://graph.microsoft.com/v1.0/users/FromAddress/sendMail 
{
"message": {
"subject": "Test mail",
"body": {
"contentType": "Text",
"content": "Test"
},
"toRecipients": [
{
"emailAddress": {
"address": "****"
}
}
],
"ccRecipients": [
{
"emailAddress": {
"address": "****"
}
}
]
},
"saveToSentItems": "false"
}
 
 Reference: 
user: sendMail - Microsoft Graph v1.0 | Microsoft Learn

Related

How to config Azure AD app for email automation

I am using the below script for sending email using azure AD portal app but getting 403 response error. could someone please help to config azure AD app registered in the portal or any changes in below code to send email automatically.
I have added the below API Permissions at Azure AD App and Redirect URI also to my account.
https://login.microsoftonline.com/common/oauth2/nativeclient
IMAP.AccessAsUser.All, Mail.Read, Mail.Read, Mail.Read.Shared, Mail.ReadBasic, Mail.ReadBasic, Mail.ReadBasic.All, Mail.ReadWrite,
Mail.ReadWrite, Mail.ReadWrite.Shared, Mail.Send, Mail.Send, Mail.Send.Shared, MailboxSettings.Read, MailboxSettings.ReadWrite, Offline_access, POP.AccessAsUser.All, SMTP.Send
User.Read
Is the app with the admin consent able to access all the mailboxes in the organization or we can restrict the access to a particular mailbox (if we can do so, could you please explain how).
import requests
def ebiw_check() -> None:
"""
Checks EBIW Application access.
Returns: None
"""
try:
data = {
'tenant': 'tenant_id',
'client_id': 'client_id',
'client_secret': 'secret_id',
'grant_type': 'client_credentials',
'scope': 'https://graph.microsoft.com/.default'}
# url to fetch the microsoft token
#url = 'https://login.microsoftonline.com/tenant_id/oauth2/v2.0/authorize'
url = "https://login.microsoftonline.com/tenant_id/oauth2/v2.0/token"
response = requests.post(url, headers=data, data=data, timeout=60).json()
print("Token fetched Successfully")
url = 'https://graph.microsoft.com/v1.0/users/sender_mail_id/sendmail'
body = {
"message": {
"subject": "Meet for meeting?",
"body": {
"contentType": "Text",
"content": "The new cafeteria is open."
},
"toRecipients": [
{
"emailAddress": {
"address": "reciver_email_id"
}
}
],
},
"saveToSentItems": "true"
}
header = {
"Authorization": "Bearer " + response["access_token"],
'Content-Type':"application/json"
}
import json
# read mail
#res = requests.get('https://graph.microsoft.com/v1.0/users/email_id/messages', headers=header)
# send mail
import urllib3
urllib3.disable_warnings()
response = requests.post(url, data=json.dumps(body), timeout=20, headers=header, verify=False)
print(response)
except Exception as e:
print(e)
ebiw_check()```
I tried to reproduce the same in my environment and got the same error as below:
Please Note: while using client credentials grant type you need to grant Application permissions and make sure to grant admin consent for the added permissions.
And I have added application permission and granted admin consent.
After granting the Application permissions I got result successfully, and returns 202 Accepted as response code.
Reference: user: sendMail - Microsoft Graph v1.0 | Microsoft Docs

Azure Enterprise App Registration - Certificate Based Authentication with JWT Assertion

Referred Azure Article URL : https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials
Problem statement : Followed steps as per the above mentioned article, but getting error like as below
Postman Request
Payload
Method : POST
URL : https://login.microsoftonline.com/{tenantId}/oauth2/token
x-www-form-urlencoded :
client_assertion_type : urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertion : { JWT Token }
tenant : XXXXXXXXXXXXXXXXXXXXXXXXXXX
client_id : XXXXXXXXXXXXXXXXXXXXXXXXXXX
grant_type : client_credentials
Postman Response
{
"error": "invalid_client",
"error_description": "AADSTS700027: Client assertion contains an invalid signature. [Reason - The provided signature value did not match the expected signature value., Thumbprint of key used by client: **'Thumbprint-Certificate-ID'**, **Found key 'Start=01/03/2022 05:06:02, End=01/03/2023 05:26:02',** Please visit the Azure Portal, Graph Explorer or directly use MS Graph to see configured keys for app Id 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'. Review the documentation at https://learn.microsoft.com/en-us/graph/deployments to determine the corresponding service endpoint and https://learn.microsoft.com/en-us/graph/api/application-get?view=graph-rest-1.0&tabs=http to build a query request URL, such as 'https://graph.microsoft.com/beta/applications/XXXXXXXXXXXXXXXXXXX'].\r\nTrace ID: 300527eb-a871-4e6f-8f5b-031ec6940902\r\nCorrelation ID: 6364e88b-3717-48cd-abcf-df7c971d1fc9\r\nTimestamp: 2022-01-05 05:36:41Z",
"error_codes": [
700027
],
"timestamp": "2022-01-05 05:36:41Z",
"trace_id": "300527eb-a871-4e6f-8f5b-031ec6940902",
"correlation_id": "6364e88b-3717-48cd-abcf-df7c971d1fc9",
"error_uri": "https://login.microsoftonline.com/error?code=700027"
}

How to create a user using azure graph api

I am trying to create a user using azure graph API. For this, I have got the token response as below:
Once I have the token, I have added this as bearer token in Authorization for the below url:
https://graph.microsoft.com/v1.0/users
and posting the below json data:
{
"accountEnabled": true,
"displayName": "Andrew",
"mailNickname": "SanAndrew",
"userPrincipalName": "andrew.san204#gmail.com",
"passwordProfile" : {
"forceChangePasswordNextSignIn": true,
"password": "password"
}
}
But getting below error:
{
" error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"request-id": "c06079d2-ff6b-4e5b-b34d-704f16bc312f",
"date": "2019-06-03T11:20:20"
}
}
}
although I have all the permissions as shown below:
Can anyone please suggest what I am doing wrong here.
One possibility for the error is that you are trying to create a user with gmail.com domain. The domain needs to be one of the verified domains in your AAD tenant.
If you want to add a gmail.com user anyway, you need to send an invitation through the invitations endpoint: https://learn.microsoft.com/en-us/graph/api/invitation-post?view=graph-rest-1.0&tabs=cs

Expected OAuth 2 access token while importing VAPID Push subscriptions into Firebase

I am trying to import vapid push subscriptions into firebase. I found some solution in https://developers.google.com/instance-id/reference/server#import_push_subscriptions. It thew following error. Please help me regarding this.
POST : https://iid.googleapis.com/v1/web/iid
Headers :
Content-Type:application/json
Authorization:key=MY_SERVER_KEY
BODY:
{
"endpoint" : "https://fcm.googleapis.com/fcm/send/my_sub_key",
"keys" : {
"p256dh" : "hidden_key",
"auth" : "hidden_auth"
}
}
}
Response:
"error": { "code": 401, "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "status": "UNAUTHENTICATED" }

Authorize a client to browse Office365 Graph API

I am trying to develop a webapp to let a user browse his Active Directory contacts.
I have two accounts: one to register the application (developer account) and the other that would be the general user who have access to Office365 (user account).
I have set up a Javascript client following the Azure AD Graph API documentation.
By now, I am able to prompt the user to login and retrieve an access token, but when I try to make a request, I always get a 401 error.
I am pretty new to Azure, so I don't really understand if the problem is in my application configuration or in my code.
I am able to browse the Graph API explorer with my user account, so I don't think he's missing the authorization to access it.
I am really confused.
I try to add all the steps I am doing, hoping someone could point out the error.
Request 1:
Url: https://login.windows.net/{my tenant id or common (both are working) }/oauth2/authorize
Method: GET
Params:
redirect_uri // my redirect url, the same I registered in my application. It is just a page that returns the content of the URL
client_id // my client id
response_type // code
state // a random generated string, not required, but reccomanded
resource // https://graph.windows.net
Response 1:
code // A long string
state // The string I sent in the request
session_state // Another string
Request 2:
Url: https://login.windows.net/{my tenant id or common (both are working) }/oauth2/token
Method: POST
Params:
redirect_uri // it won't be necessary, but in some post they reccomand to add it
client_id // my client id
client_secret // my client secret
code // the code retrieved from Request 1
grant_type // authorization_code
state // a random generated string
resource // https://graph.windows.net
Response 2:
token_type // Bearer
access_token // a long token
id_token // exploring it with the JWT tool, shows it has the correct app id
refresh_token // a long code
resource // the same I sent in the request
scope // Directory.Read UserProfile.Read
expires_in
expires_on
a couple of other irrelevant keys
Request 3:
Url: https://graph.windows.net/{the domain the logged account belong to}/contacts
Method: GET
Headers:
Authorization: Bearer {the access token retrieved from request 2}
Params:
api-version = 1.5 // The value suggested in the documentation.
Response 3:
{
"odata.error": {
"code": "Authentication_MissingOrMalformed",
"message": {
"lang": "en",
"value": "Access Token missing or malformed."
},
"values": null
}
}
This is the content of my Access Token:
{
typ: "JWT",
alg: "RS256",
x5t: "foofoofoofoo"
}.
{
aud: "https://graph.windows.net",
iss: "https://sts.windows.net/<SOMEGUID>/",
iat: 1418224761,
nbf: 1418224761,
exp: 1418228661,
ver: "1.0",
tid: "<SOMEGUID>",
amr: [
"pwd"
],
idp: "https://sts.windows.net/<SOMEGUID>/",
email: "myuseremail#contoso.com",
unique_name: "myuseremail#contoso.com",
sub: "barbarbarbar",
altsecid: "<an-id>",
family_name: "Last Name",
given_name: "First Name",
appid: "<MY APP ID>",
appidacr: "1",
scp: "Directory.Read UserProfile.Read",
acr: "1"
}
Answer
So, it looks like user must have the "can consent" authorization to authenticate to his own active directory, and this can be provided just by the administrator.
I posted the same request on the MSDN forum and I got the same answer.
I want sincerely thank #Jason Johnston and #Dan Kershaw since this problem was driving me nut and I would never be able to sort it out without their help.
Unfortunately I can award the bounty to just one of them, so I decided to give it #Jason Johnston for the great patience he had in supporting me in this and another discussion.
I believe if you actually want to browse the Active Directory, and not just read the authenticated user's profile, you need administrator consent for a web app. See http://msdn.microsoft.com/en-us/library/azure/b08d91fa-6a64-4deb-92f4-f5857add9ed8#BKMK_Graph
If you already knew that, then maybe it's a problem with how you've registered your app or the token itself. Make sure you've selected the appropriate permissions per that link in your app registration. If those look right, then you can check the token. There's a handy little token parser here: http://jwt.calebb.net/. Just paste in the value of your token and it will show you the decoded JSON. Look at the scope or scp parameters.
{
"typ": "JWT",
"alg": "RS256",
"x5t": "asdfsadfasdfsa"
}
{
"aud": "https://graph.windows.net/",
"iss": "https://sts.windows.net/<SOMEGUID>",
"iat": 1418158549,
"nbf": 1418158549,
"exp": 1418162449,
"ver": "1.0",
"tid": "<SOMEGUID>",
"amr": [
"pwd"
],
"oid": "<SOMEGUID>",
"upn": "admin#contoso.com",
"unique_name": "admin#contoso.com",
"sub": "askdljalsdfs",
"puid": "1003BFFD88937280",
"family_name": "Administrator",
"given_name": "MOD",
"appid": "<YOUR APP ID>",
"appidacr": "0",
"scp": "Directory.Read user_impersonation UserProfile.Read",
"acr": "1"
}
The token you've pasted is missing the OID and UPN, and that'll probably be why you are seeing this error. I'll have to go back and check how this access token could have been issued without those claims.

Resources