Microsoft Graph API: Limiting MSAL Python Daemon app to individual user access - python

I am building a Python Daemon app to download files which are accessible to an individual O365 user via Graph API. I am trying to use ConfidentialClientApplication class in MSAL for authorization.
In my understanding - this expects “Application Permissions” (the API permission in Azure AD) and not “Delegated permissions” for which, admin has to consent Files.Read.All.
So the questions I have are:
Does this mean, my app will have access to all the files in the organization after the admin consent?
How do I limit access to a Daemon app to the files which only an individual user (my O365 user/UPN) has access to?
Should I be rather be using a different auth flow where a user consent be also part of the flow: such as on-behalf-of (or) interactive (or) username password?
Thanks!

Does this mean, my app will have access to all the files in the organization after the admin consent?
Yes, it is the downside of application permissions usually.
How do I limit access to a Daemon app to the files which only an individual user (my O365 user/UPN) has access to?
I'm pretty sure you can't limit a daemon app's OneDrive access. You can for example limit Exchange access for a daemon app.
Should I be rather be using a different auth flow where a user consent be also part of the flow: such as on-behalf-of (or) interactive (or) username password?
It would certainly allow you to limit the access to a specific user. In general I recommend that you do not use username+password (ROPC); it won't work any way if your account has e.g. MFA. The more secure approach would be that you need to initialize the daemon app once with Authorization Code flow. This gives your app a refresh token that it can then use to get an access token for the user when needed (and a new refresh token). Note it is possible for refresh tokens to expire, in which case the user needs to initialize the app again.

You can limit the Application (Admin approved) permissions to specific resources (at least for some resources - e.g. mailboxes, calendars, SharePoint sites, ...)
Using Application Access Policy
An example for using this to restrict mailbox access to one or more users is:
https://learn.microsoft.com/en-us/graph/auth-limit-mailbox-access#configure-applicationaccesspolicy
This approach isn't possible to set currently in the MSGraph Application definition. Your admin has to use Powershell to associate an Access Policy to an Application definition.
SharePoint sites restriction
For SharePoint sites, you can use the MS Graph Sites.Selected Application permission to have Admin approved access to specific SharePoint sites.
https://devblogs.microsoft.com/microsoft365dev/updates-on-controlling-app-specific-access-on-specific-sharepoint-sites-sites-selected/

Related

How do I to give my web project access to my Gmail account?

I am trying to adapt to Google's change in smtp policy on 5.30.22 that prevents 3P apps to have access to gmail account. I want to give my web project hosted on heroku access to be able to login programatically to my gmail account. I checked out some posts including this one, but I'm just not seeing what is expected in my settings.
In that gmail account, I go to Security -> Less secure app access and confirmed it is, in fact, no longer available. I saw nothing else in Security that seemed relevant.
Then, I try Data & Privacy -> Data from apps and services you use -> Apps & Services -> Third-Party Apps With Account Access. Clicking on that takes me to
Apps with access to your account, where I see You haven’t given any apps or services permission to access your Google Account. Learn more (<-- link to https://support.google.com/accounts/answer/3466521?hl=en). That link brings me to Manage your account permissions -> Manage third-party apps & services with access to your account.
I then go to Review what a third party can access. Steps for that are:
Go to the Security section of your Google Account.
Under “Third-party apps with account access,” select Manage third-party access.
Select the app or service you want to review.
...but in step #2, there is no Third-party apps with account access or Manage third-party access link/section in my security page.
How do I add an app I'm working on to that list?
UPDATE - I saw https://support.google.com/accounts/answer/112802?hl=en&ref_topic=7188760, which is "Use your Google Account to sign in to other apps or services". Is this what I need? It says to:
Go to an app or service you trust.
On the sign in page, select Sign in with Google, Log in with Google, or Join with Google.
I go to my app (hosted on heroku), but the "Sign in with Google" option is not there.
Due to the removal of Less secure apps & your Google Account you can not use a users login and password to access googles smtp server.
You have two sevral options.
Switch to using the gmail api and authorize your application using Oauth2 and store a refresh token. Make sure to set your app to prodctuion or the refresh token will expire after seven days.
Use xoauth2 with your request to the smtp server. You will then need to use Oauth2 to authorize the application and store a refresh token. Make sure to set your app to production or the refresh token will expire after seven days.
If you have 2fa enabled on that account then you can create an apps password. Sign in with App Passwords Once you have created this password you can then use it in place of the actual password in your code.

How can I login to two django applications with a single access credential?

I currently have several applications developed in django, and they ask me that with a single credential and depending on the permissions assigned to each user, they can access the different applications, how could I do that taking into account the session management middleware what does django have?
If you don't want it to become monolith, you must create an Auth service that handles permission, credentials, scopes and etc. This service should communicate to two other services for granting access or check permissions and stuffs like that.
Take a look at OAuth 2.0

GAE Python: Control access based on GSuite group

Is it possible to control access to a request handler entirely or some parts therein based on what GSuite for Education/Business group a user belongs to?
It is possible to have code check the GSuite group membership using the Directory API from the Google Apps Admin SDK. You'd probably be interested in one of:
retrieve all groups for a member
retrieve a group's member (if just one or a few groups are to be checked).
You'll need to
Enable the API access in the G Suite Admin console:
G Suite administrators have access to the Admin SDK–a collection
of Application Programming Interfaces (APIs). With these APIs, you can
build customized administrative tools for your G Suite products.
Before you can use the Admin SDK, you need to enable API access in the
Google Admin console.
You must be signed in as a super administrator for this task.
Enable API access
To verify that API access is enabled:
Sign in to your Google Admin console.
Sign in using an administrator account, not your current account some_user#gmail.com.
From the Admin console dashboard, go to Security > API reference.
To see Security on the dashboard, you might have to click More controls at the bottom.
Make sure the Enable API access box is checked.
At the bottom, click Save.
enable the Admin SDK API from the Google Apps APIs group in for your GAE app's API Manager page
install the Google API Client Library in your GAE app (if not already done)
address authentication, posibly using your GAE app's service account. See Google API Client Libraries Authentication Overview. And maybe related App Engine OAuth2.0 authorized cron job to analyze Google Sheet.
(if you want to) restrict app access to only your GSuite domain, see Restrict App Engine access to G Suite accounts on custom domain
code your access control logic using the directory api to obtain group membership info

Do I need a service account for Google Directory API?

Bear with me, a total novice at APIs. I'm trying to build a web-app that allows my colleagues within the same domain to view a list of all other users in the domain after logging in. I'm attempting to use Google Directory API. Think of a roster, or org chart of sorts. I plan on using Django and python to build this.
https://developers.google.com/admin-sdk/directory/
I've created an OAuth 2.0 client ID, but I don't know if I need a service account to actually access the list of users. Additionally, I don't manage this domain, do I need to have the administrator grant priledges to this service account?
If you create a service account, the account still has to "act" like a user on the domain, and that user has to have privileges to whatever scope you're using. If you can get the domain admin to give you access to list users, ask him/her for the readonly scope(to imply the impossibility of your app damaging the site)
When you create a service account you'll get a key that will authorize you to act as an account on the domain.
I don't think that you need a service account, but it's a little easier in my opinion.
If you don't manage that domain you cannot get a list of users.
You would need authorization for that service account to use the relevant scope(s). If you can't do it yourself and can't get it done by the administrator then this conversation is over :(

Authentication with Azure Active Directory - how to accept user credentials programmatically

Is there any way to login via web application or web api to Azure Active Directory (with AD credentials) using my own username and password page which is hosted outside of Azure?
From my investigation it seems there is no programmatic way to send username and password to authenticate users with Azure AD (if you hosted an app outside of Azure)
Not sure if they consider this to be a security hole of some sort (i dont think it is it https is enforced?)
Seems like you can only authenticate users by going through the code grant (which means popping out of our application to sign on to an external site).
Ultimately I want to create a python flask api that can authenticate against Azure AD directly if possible.
I have done this in the past (with other auth systems) with the Oauth grant_type=password to send username and pass, but dont think this is supported in Azure AD (correct me if im wrong?)
I know grant_type=client_credentials is supported, but that seems like its service to service auth, which is not quite what im after
http://msdn.microsoft.com/en-us/library/azure/dn645543.aspx
If its not possible to have a login page hosted outside of Azure for this, is it even possible to have one inside of Azure, seems like from examples here:
http://msdn.microsoft.com/en-us/library/azure/bc8af4ff-66e7-4d5b-b3d4-c33d2c55d270#BKMK_Browser
There is no custom login page with a password field .. (only open id logins it seems)
The Resource Owner Password Credentials Grant (grant_type=password) flow is supported by Azure Active Directory. However, before using it, consider if it is truly required. As it says in the OAuth 2.0 RFC:
The resource owner password credentials (i.e., username and password) can be used directly as an authorization grant to obtain an access token. The credentials should only be used when there is a high degree of trust between the resource owner and the client (e.g., the client is part of the device operating system or a highly privileged application), and when other authorization grant types are not available (such as an authorization code).
If you have determined that the other supported flows will definitely not work for your scenario, then also be sure to follow the second bit of advice in the RFC:
Even though this grant type requires direct client access to the resource owner credentials, the resource owner credentials are used for a single request and are exchanged for an access token. This grant type can eliminate the need for the client to store the resource owner credentials for future use, by exchanging the credentials with a long-lived access token or refresh token.
(Emphasis added in both cases.)
There's a .NET and ADAL sample on GitHub that uses this flow, and it should be simple enough to implement in Python: https://github.com/AzureADSamples/NativeClient-Headless-DotNet
Edit: You can host your application anywhere you want, it doesn't need to be on Azure. This applies to all flows.

Categories