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

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

Related

Azure Active Directory: how to get user's object id via auth code flow (MSAL)?

I have developed web application (Python/Django) for my client and he wants me to add SSO via Azure Active Directory that he setup. Also I need to fetch user profile information (email, upn) and update it when it changes in AD.
I managed to get SSO working using MSAL with auth code flow and able to send requests to Graph API on behalf of user to get profile information (/me).
To get profile updates I created subscription (webhook) to /users resource using app identity (client credentials grant flow).
The problem is that I can't understand how to correlate users I get from subscriptions with users I get from auth code flow via MSAL. Notifications from subscriptions give me ids i can find on azure portal (GUID), but profile information requests on behalf of user dont give me same ids. There are ids, but these ids are differenet (something like c66b9ba73bcba166)
As juunas mentioned, the object id is typically oid or sub.
Example using jwt.ms to examine the ID token:
Also, if your app needs to distinguish between app-only access tokens and access tokens for users, you can use use the idtyp optional claim.

DocuSign ISV app authentication questions

So if I have an app with many users on board, all from different companies/places, I'm thinking that an individual 'connect to docusign' with OAuth is the right flow.
I think I could have an admin connect their account and impersonate the entire company, but it doesn't sound great from a security perspective.
I also see some places asking people for their docusign admin username/password which I assume is highly discouraged.
Question: I am planning on using just one 'integration' for my app to manage all this, should I be aiming to use one integration per docusign account I interact with? i.e. Should I ask the companies to each make an integration and give me the id/secret?
Several questions here:
OAuth flow
Yes, if your DocuSign users will have their own DocuSign user IDs then you can add a "Connect to DocuSign" button and use the OAuth Authorization Code grant flow. Include the extended scope so you can use the refresh token on an ongoing basis. Remember to use secure non-volatile storage for the refresh tokens since they can be used to obtain access tokens.
See Authentication for ISVs
I think I could have an admin connect their account and impersonate the entire company, but it doesn't sound great from a security perspective.
Correct. It is best to use JWT grant (impersonation) only if the end users can't use the Authorization Code grant flow. For example, if your app is a back-end app or doesn't have a web interface.
JWT (impersonation) flow is fine when needed, but it incurs significant customer confusion and work to provide consent. So Authorization Code grant is preferred if it fits your needs as an ISV.
One DocuSign client_id (integration key) or one per end-customer?
Best is to use one DocuSign client_id (integration key) for your application, not one per customer. See ISV docs
Should I ask customers to give me an integration key and secret that they created?
Please no. Your customers are not developers. Asking them to become DocuSign developers and create a client id (integration key) is a lot of work for them. There's no need to go down this path. Just use the same OAuth Authorization Code grant redirect_uri for all of your customers. Remember that you can use the state parameter as needed to handle the OAuth redirect from DocuSign.
Use your free partner account to manage your application's client id and its settings.
asking for a DocuSign administrator name/pw from your customers
Correct: don't do that!
you want your customers to set up their DocuSign accounts in a specific way
Your app can do that for them by having including a "Setup DocuSign account" button. That button (when used by an authenticated DocuSign admin) would update the account settings as your app needs. For example, setting up a Connect
users have multiple accounts
Extra: remember that it is common for DocuSign customers to have access to multiple DocuSign accounts. Eg, a general account, an account for HR, etc. They may or may not set up a special account for your application, depending on the use case.
After a user authenticates, your app can either use the user's default account, or if your application uses a dedicated account, check that the user has a access to it.

Consume Microsoft Graph API from backend service (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).

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.

Resources