Nodemailer with gmail service account - gmail-api

I'm implementing a "no-reply" account for sending automated emails. Do I need the access key/refresh token, and if so where can I generate them for a service account?
At the moment I have this:
noreply = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
type: 'OAuth2',
user: smtpConfig.client_email,
serviceClient: smtpConfig.client_id,
privateKey: smtpConfig.private_key,
}
});
Which unfortunately gives me this:
{ Error: Invalid login: 535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8 https://support.google.com/mail/?p=BadCredentials h81sm3513839itb.18 - gsmtp
at SMTPConnection._formatError
...
Thanks!

you do not need a refresh token with a service account and nodemailer will generate the access key for you automatically
You cannot only use a service account to send emails for a GSuite account and not a gmail account.
If you have a gmail account you can use 3-legged OAuth2 authentication
Or turn on 2FA, generate an App Password and use that as seen here
If you ARE using a GSuite account you can use the ServiceAccount but you will have to make sure it has G Suite Domain-wide Delegation as described here and then you need to give access to the GSuite Domain as described here

Related

InteractionRequiredAuthError: invalid_grant: AADSTS50076

Error message: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access 'bxxx-xxxx-xxxxa'.
I am getting this error intermittently, while accessing token with auth code.
Token endpoint fails with error code 400.
Request body in browser contains:
POST: https://login.microsoftonline.com/tenantID/oauth2/v2.0/token
clientId,
scope - xxxxxxxx/.default openid profile offline_access
grant_type: authorization_code
code
redirect_uri
and here is MSAL configuration: (we are using react-msal 1.4.3)
const msalConfig = {
auth: {
clientId: env?.ClientId,
authority: env?.Authority,
redirectUri: env?.RedirectUri,
postLogoutRedirectUri: env?.PostLogoutRedirectUri,
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true,
},
scopes: [env?.AuthScope],
}
Please let me know if anyone has encounter this issue before and found any solution for it.
• It is because your administrator has enabled the security defaults setting in ‘Manage security defaults’ section in Azure AD tenant properties as shown below in the snapshot. When you enable this option, Azure AD mandates all users to register for Azure AD multi-factor authentication, requires the same for administrators and enforces it, blocks legacy authentication protocols, and protects privileged activities like access to the Azure portal.
Thus, if you are assigned a role of ‘Administrator’ of any sort, i.e., Global, Authentication, Application, Billing, Exchange, etc., then your ID would be required to do multi-factor authentication. Also, please ensure that you are not using any older protocol and legacy authentication since those doesn’t have access to multi-factor authentication.
As a result, this would help in resolving the issue and the subsequent error that you are facing. For more information, kindly refer to the below links given: -
https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/concept-fundamentals-security-defaults
https://learn.microsoft.com/en-us/answers/questions/494959/aadsts50076-ue-to-a-configuration-change-made-by-y.html

Unable to Send email using microsoft Graph API using delegated permission with Username and Password provider

I am trying to send email using UserNamepassword provider with delegated permission but getting error as below
AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '00000003-0000-0000-c000-000000000000'. Trace ID: 66ecbe3d-56d1-4850-8310-dd33cb8d3900 Correlation ID: b2f61146-44d3-4997-ab99-5370bbac6b04
When I tried with Application permission with send.mail, I am able to send email as any user.
but as per the company restrictions i need to send email using delegated permission.
How to achieve this as error is with respect to Multi factor authentication as MFA has been enabled on our account.
IPublicClientApplication publicclientapplication = PublicClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.Build();
UsernamePasswordProvider authprovider = new UsernamePasswordProvider(publicclientapplication, scopes);
await graphServiceClient.Me
.SendMail(email, false)
.Request().WithUsernamePassword("Username", passwordstring(stringpassword))
.PostAsync();
Please help here with options.
If the user has multi-factor authentication (MFA) enabled, then you can’t use username/password to obtain tokens, because ROPC flow does not support MFA, according to the documentation:
If users need to use multi-factor authentication (MFA) to log in to
the application, they will be blocked instead.
The easiest way is to use the auth code flow, which supports users with MFA enabled to log in to the application. When using this flow, you need to log in to the user to obtain the authorization code, and then use the authorization code to redeem the access token.

The Reply URL specified in the request does not match the reply URL's configured for the application

I am currently using Microsoft adal angular for Azure active directory authentication and below if the configuration settings for the same.
MsAdalAngular6Module.forRoot({
tenant: 'xxxxxxxxxxxxxxxxxxx',
clientId: 'xxxxxxxxxxxxxxxxx',
redirectUri: window.location.origin,
endpoints: {
"xxxxxxxx": "xxxxxxxxxxxxxx",
},
navigateToLoginRequestUrl: true,
cacheLocation: 'localStorage',
loadFrameTimeout: 60000
}),
I have set reply URL as https://xxx.azurewebsites.net/ in Azure app registrations.
The above configuration works fine if I use https://xxx.azurewebsites.net/ and enter into the application. But when I use https://xxx.azurewebsites.net/dashboard and enter my credentials it is throwing the error mentioned in the subject and not allowing me to go in.
I know that the Azure has blocked wild card configurations in Active directory. Is there a way for me to configure the settings to successfully authenticate If I copy-paste any deep link from the application.
Any help would be really appreciated and thanks in advance.
When the redirect_uri in the authorization request mismatches the redirect url configured in Azure AD registrations, you will encounter this error.
So if you want to use https://xxx.azurewebsites.net/dashboard in your request, you should also add it as the redirect url of your Azure AD registrations.
Update:
Based on our discussion, you just need to specify the redirect URL in your code as the same url as what you have configured in your Azure AD app: https://xxx.azurewebsites.net to meet your requirement.

Integrate Azure AD with AngularJS and call CORS web api

After going through the article https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v1-angularjs-spa, we have created a web application named ToDoSpa and web api named ToGoApi registered in Azure Active Directory and are able to authenticate but the problem lies in consuming the web api including the endpoints as
AADSTS65001: The user or administrator has not consented to use the application with ID '2528e8f3' named 'ToDoSpa '. Send an interactive authorization request for this user and resource.
Trace ID: df70a02e-6a53-4899-8319-0ba440540500
Correlation ID: 699515a6-dccb-421e-92ae-e9b5a700ad1b
Timestamp: |interaction_required".
Client Id:
ToDoSpa->2528e8f3
ToGoApi->815933a4
In ToDoSpa,we have defined the scopes for the application ToDoSpa as "User.Read and Directory.Read.All" and authorized the client application using the client ID of web api(815933a4) in Expose API. In App permission, we have included ToDoSpa and have grant consent the application.
app.js
var endpoints = {
"https://graph.microsoft.com": "https://graph.microsoft.com",
"https://localhost:44392/api/weather": "https://firstupconsultants.onmicrosoft.com/ToGoApi"<!--localhost:App Id Uri of Server-->
};
adalProvider.init({
instance: 'https://login.microsoftonline.com/',
tenant: '<tenant-id>',
clientId: '<client-id of server>',
endpoints: endpoints,
extraQueryParameter: 'prompt=admin_consent'
}, $httpProvider);
}]);
//Get
weather1.getWeather = function () {
return $http.get("https://localhost:44392/api/weather").then(succeessCallback, failedCallback);
function succeessCallback(weather) {
//$scope.weather = weather.data;
weather1.items = weather.data;
}
function failedCallback(error) {
console.log("An error has occurred:", error);
}
}
web.config
<add key="ida:Tenant" value="<tenant-id>"/>
<add key="ida:Audience" value="https://firstupconsultants.onmicrosoft.com/ToGoApi"/>
<!--localhost:App Id Uri of Server-->
Typically, when you build an application that uses application permissions, the app requires a page or view on which the admin approves the app's permissions. This page can be part of the app's sign-in flow, part of the app's settings, or it can be a dedicated "connect" flow.
When you're ready to request permissions from the organization's admin, you can redirect the user to the Microsoft identity platform admin consent endpoint.
Here is sample URL for the same:
GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions
When you want to enable the users on other tenant can use the application, the application required to give the consent first. To do that you can make a HTTP request to grant the admin consent easily by using the prompt parameter.
You can read about this in detail in below doc:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#request-the-permissions-from-a-directory-admin
Additional reference:
https://blog.mastykarz.nl/implementing-admin-consent-multitenant-office-365-applications-implicit-oauth-flow/
Hope it helps.

Microsoft Graph API Password Reset Only Accepts Null password

I am trying to reset another user's password through the Graph API (specifically graph.windows.net, though the same behavior occurs using graph.microsoft.com as well).
I believe all security is properly set up. The application registration has the Directory.ReadWrite.All permissions and the service principal is a Global Administrator. There are no errors regarding insufficient privileges, but whenever I try to provide a password inside the password profile I get an error.
PATCH request to
https://graph.windows.net/{tenant_id}/users/{userPrincipalName}?api-version=1.6
with the following body gives me a 204 response.
{
"passwordProfile": {
"password": null,
"forceChangePasswordNextSignIn": true
}
}
But the same request with a password of "P#ssword1" or any other valid password returns a 400 Bad Request with the message "One or more properties contains invalid values."
Anyone encountered anything like this? These are accounts being synced from local AD but the password reset has been turned on in Azure and you can manually reset the passwords in AAD. Any help or advice is much appreciated.
It turns out this was a problem with how AD sync is set up in their environment. Apparently a federated domain syncing to Azure AD locks out the ability to reset passwords via the Graph API but the error messages don't tell you its a permissions issue.
It's outline here under unsupported operations, my problem was not understanding the full AD environment set-up: https://learn.microsoft.com/en-us/azure/active-directory/authentication/concept-sspr-writeback
According to your description, I assume you want update user's password through the Graph API.
According to this document, when we update the passwordProfile property, the following permission is required: Directory.AccessAsUser.All.
Based on my test, we can modify someone's password by using the following steps:
Grant the permission by following this document.
Check the password in the profile whether satisfy minimum requirements as specified by the passwordPolicies property.
Use the following request to update someone's password.
The Request URL:
PATCH /users/{id | userPrincipalName}
And the request body:
{
"passwordProfile": {
"forceChangePasswordNextSignIn": true,
"password": "P#assword1"
}
}
If successful, this request returns a 204 No Content response code.
You're calling the wrong URL, graph.windows.net is the legacy Azure AD Graph API. The Microsoft Graph APIs are located at graph.microsoft.com. While these APIs are similar in function, they're calling paterns are very different.
As kikang mentioned, in order to change a user's password you need need to request the Directory.AccessAsUser.All scope. There are a few important cavetes with this scope:
This is a Delegated scope, so it can only be requested when using Authorization Code or Implicit OAuth flows. It cannot be used with Client Credentials.
Before a User can consent to Director.AccessAsUser.All, you must first obtain Admin Consent from an Admin on the user's AAD tenant/instance.
Once you have the proper scopes consented, you need to issue a PATCH to the /user resource.
Your call will look similar to this:
PATCH https://graph.microsoft.com/v1.0/me
Content-type: application/json
{
"passwordProfile": {
"forceChangePasswordNextSignIn": true,
"password": "A-Strong-Password"
}
}

Resources