Consume Microsoft Graph API from backend service (node.js) - node.js

I want to send emails using Microsoft Graphs API from a backend service developed in node.js, that has no interactions with the user.
If I understand it correctly from this paragraph, if I use the Get access without user procedure, the administrator will have to give me some rights and then I will have those rights on every user account in the organization. This is not my goal, I only want to have those rights for one specific account, for which I have the login and password.
Is there a way to log in with an office365 account without user interaction?
Thanks :)

No. You need to have the user authenticate in order to obtain the initial access token and refresh token (to refresh your permission to access the account).

Related

Is it possible to have a permanent token

I have a web application and I want to give the ability for the user to connect his Outlook account with my web application.
Which will give the ability to create a meeting in his calendar once he adds it in the system.
I've create an Azure AD application, the user can login and generate an access token which I can create the meeting using Graph API.
and refresh token isn't working from backend service.
But my problem is that I need a permanent token so the user doesn't have to login again,
same as the outlook calendar app in slack.
Is there a specific configuration that I need to make this happen?
Thanks

Access token and authentication for guest user

TLDR:
is it possible to have guest account, like guest#organization.onmicrosoft.com, at company's MS Office 365 cloud that will have "read" permission to organization's users calendars and events with constant access token? By constant access token I mean that I sign in once for this guest user and receive constant access token from Azure AD (like application access authentication but as guest account).
I have my own company's MS Office 365 account with some users in it. There is one global administrator account and few regular users.
There is second company, let's call it XYZ, with their own MSO365 account with many of administrators and users. Big company.
Now I'm writing simple app where I need to have access to read XYZ company's users calendars and events. I have list of required users in my app with proper MSO365 ID's.
I think that 'read' privilege is enough since we can send invitation for events through ordinary email message.
My App will read user events through MS Graph API etc. with some logic and realease it (send invitations for events etc.) with CRON jobs.
And here is my problem with authentication.
I don't want to have "application access" Azure AD privileges at my App. I know the XYZ company security policy won't apply it since "application access" gives access to all accounts at organization. Application access means that XYZ company's global administrator apply application privileges for my App by single sign in into Azure AD. If he do so i have Access token which i can use for API calls at my app withoud need of additional authentication.
I can't use "user access" Azure AD authentication neither.
Due to my CRON jobs and API calls which fire then.
User access means that user need sign in at Azure AD login service what gives me Access token and Refresh token for API calls. Those tokens are 1 hour lifetime.
So I though about: if there is possibility to have a guest account at XYZ company's MSO365 that would let me use authentication mechanism like the "application access"?
By this I mean that XYZ company's global Admin creates me a guest account like guest#xyz.onmicrosoft.com which will have access to read users calendar and events. What is more I need this account to have constant access token which I can use in my cron job's api calls with no need to sign in at Azure AD.
The question is: is it possible? If so how to do it?
The only way there (AFAIK) is to use refresh tokens.
Application-level access is more robust but requires organization-wide access.
So you use delegated access (user access), store refresh tokens somewhere.
You can use those tokens basically indefinitely,
however certain events can expire the refresh token.
It doesn't happen often, but it can happen.
In that case you would need the user to login again so you can get a new refresh token.
You should also store the new refresh token that you get when you acquire tokens using a refresh token.
This new token can overwrite the old token for that user.
And of course keep in mind refresh tokens are user-specific so you gotta store one for each user.
This is the approach that one of our bigger apps takes.
If we fail to acquire a token in the background process,
that user gets a flag set on them that their token does not work,
and they'll get a notification that they need to re-authenticate for the feature to start working again.

How to get microsoft graph token without popup user login page?

I need to write a backend app to read & write one company emailbox.
I have registered Active Directory Application and granted Delegated permissions (read and write to user mailbox).
Question is how to get the token needed for authenticate the graph api calls(for example ListMessages).
From the document I coundn't find any working example for backend app aquiring token and make api calls.
There are two endpoint versions:
Azure AD and Azure AD v2.0 endpoints;
And two authentication method:
1. Get access on behalf of a user
https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_user
2. Get access without a user
https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service
What shoud I use ? Really confused.
Thanks all.
According to your description, I assume you want to get an access token without user login page.
Based on my test, we can get an access token that run as a background services or daemons.
It requires administrator to grant the access permission once, then user will not see login popup window anymore.
For more detail, we can refer to this official document.
Sounds like you are looking for Resource Owner Password Credentials grant flow.
However its usage is not recommended.
It does not work in these scenarios:
User has MFA
User password has expired
User is federated (MS account/Google/on-prem AD)
The only scenario that I can think of where this flow is okay is integration tests of APIs where you need to test scenarios where you call your API on behalf of a user.
Here is a better way to do what you want:
Require an application permission to access user emails and have the admin grant it. Now you can use client credentials grant flow to get a token anytime you need one.
Use delegated permissions, have the user sign in once with Authorization Code grant flow. Then exchange the code for an access token and a refresh token. Store at least the refresh token somewhere secure. Use refresh token whenever you need a new token.
The first approach is more reliable but requires broader permissions.
The second has tighter security (only users who have authorized access can have their email read), but has slightly less reliability.
Refresh tokens can be invalidated, in which case you'll need the user to login again.

Sync with Azure Active Directory with a multi-tenant app (receiving user notifications)

I've developed a feature on my web-site that allow to log-in using Azure.
So users in my web-site can sign-in using:
Azure (OAuth2). We're using a multi-tenant app. We're just using the application to log in users. So we don't really use the Access-Token to make requests. We just use the access-token to obtain the user email (decoding it with JWT).
Their own email-password they can set on my site.
This creates a problem:
Imagine an person that starts working in a company. The IT team give him an email that belongs to their azure account (with their account domain). This team also have an account on my site (configured with the same domains they use on Azure). So this user will try to log in my site using his credentials. We'll create his profile on their company account (due to the email domain). He sets his password. Sometimes he use Azure to log-in and sometimes he use his email-password to log-in.
The next month and, this person get fired. The IT team delete him from Azure. Although, the IT team forget about deleting him also on my site. So this user has permissions to sign-in with his email-password credentials and still be able to see private information (he can even delete private files).
I would like to know if there is a way to sync my app with every Directory that is using it. So I would be able to receive user action notifications (like user deletions). It would be great to receive a call to an endpoint with information about users important actions. This way we'll be able to delete the user also from our platform. So the company can forget about deleting an user on my site without having the stolen-information problem.
PS: I've seen you have a logout sync using SAML, but I wonder if we would be able to receive other kind of notifications, because we don't want to log-out the user when this logs-out from Azure.
If you have permission from the ex-user tenant administrator to access their directory, you can check if the user is listed or not by using Microsoft Graph API
I've been talking with microsoft support and there is no way of having microsoft calling our endpoint to receive some notifications.
So the only solution is ask for admin permission or, having the refresh_token from Oauth2, check the user still appears on Graph (https://graph.microsoft.com/v1.0/me).

Retrieving an access token with admin consent : how access the data of all the users of the organization?

In my third-party web application of Office 365, I want to have access to the contacts, events and emails of all the users from the organizations who installed my app.
The thing is I don't want that all these users have to grant me access, I just want one admin of the org to grant access for my app and then be able to retrieve the data I need for all the users.
To test for one organization, I logged in as the admin and proceed to the Oauth2 authentication to retrieve the access token and in the first request (the GET one to retrieve an authorization code) i add the parameter prompt=admin_consent.
With this access token, I can access the data (emails, contact, event) of the admin
for instance for the contacts
uri: https://outlook.office365.com/ews/odata/Users(adminemail)/Contacts
but not the data of the other users of this org with this uri
uri: https://outlook.office365.com/ews/odata/Users(useremail)/Contacts
The only thing I can do is retrieve an access token for each user but it supposed that each user has to authorize the access to the app but it's very cumbersome.
So, i don't see what enables the parameter prompt=admin_consent and how to use it. Does anybody know what it does?
And my question is: how can I do to access the data of all the users of one organization when the access has been granted by one admin?
Thank you!
Thanks for your question! The scenario you are interested in (an app accessing data of all users of an organization once an admin grants access to the list) is not yet supported but is prioritized high on our list of features to add.
[UPDATE] Support for app accessing data of all users in a tenant is supported for Office 365 Mail, Calendar and Contact REST APIs. Please see Building Daemon or Service Apps with Office 365 Mail, Calendar, and Contacts APIs (OAuth2 client credential flow) for more info.
The scenario prompt=admin_consent is intended for, is different from your scenario. Admin consent simply means that the admin allows this app in the organization without the individual user to see the consent screen after signing on to the app. This special "I as the admin provide consent for this app on behalf of all my users" is triggered by the "prompt=admin_consent" parameter that is passed in during the authorize request. However, this doesn't allow the app to get AccessTokens for any user. Each user still has to get the app, sign in, and the app will hit the authorize endpoint and get a Refresh/AccessToken for the signed in user.
Please let me know if you have any questions or need more info.
Thanks,
Venkat

Resources