Google Sheets API Log in using own account - c#

I am writing a .Net code to populate Google sheets from console application.
Reference article https://www.hardworkingnerd.com/how-to-read-and-write-to-google-sheets-with-c/
I understand that we should give access to the service account.
In my organization, I could not share it with the service account and i am hitting the below error.
Sorry, an item cannot be shared outside of [Company]
Is there a way to access/read/write the Google sheets via my own account
Any help on this (.net code) using own account instead of service account will be much appreciated.

Your console application needs to provide credentials that authenticate it, and allow asking for consent from the user (you) for the scopes permitted for that app.
This means, when your application makes a request to the Sheets API, it provides its credentials, and if allowed, the API will redirect the user to the app's consent screen, When consent is given to the application, it is able to perform requests in the name of the user.
The service account is an account that can impersonate a user in the domain, only if it was given domain-wide-authorization. Otherwise it can only access application data (data belonging to your own application).
So if you want an application to access user data, then it (the app) must have valid credentials, for the enabled scopes of the enabled APIs.
You can get OAuth 2.0 Client IDs credentials for your app by following the first 4 steps of this answer and use those instead of the service account credentials.
References:
Sheets API codelab recommended
Sheets API documentation

Related

Microsoft Identity Headless Login

I have a Windows service that cycles through four different mailboxes, reads the emails into a CMS system, then deletes the emails. I have been using simple sign-on with IMAP, but apparently Microsoft has deprecated this option and I need to move to Microsoft Identity.
In my corporate environment I cannot use an app account due to security issues, so I have to use user logins.
Can I authenticate to a user using Microsoft Identity headless in a Windows service? I don't want to have to authenticate manually each time the service starts up, plus I am not even sure if I can have 4 Microsoft user accounts active at the same time. Any direction would be appreciated.
I'm assuming you mean the EWS web api.
To use Microsoft oauth you need a azure application registration with the delegated api permission EWS.AccessAsUser.All.
With this setup you can either access the mailbox of a user with the users login token (i.e. either using their username and password or interactive user login) or you can use user impersonation.
To use user impersonation you need a username and password of a user that is allowed to access the mailboxes you need access for.
Another way to go is to setup a azure application registration with a application api permission to EWS.AccessAsUser.All. This allows you access to all mailboxes. I would not recommend this as people may not like the fact you can access any mailbox in an organization.
Following the code examples from the URL above will get you access to only online mailboxes. To support a hybrid setup where the mailbox is either online or on-premise the missing link is to autodiscover the mailbox server URL(so you don't hardcode it to the Exchange online URL). This has been made very simple with autodiscover v2. It's a simple https request where the result is the URL of the exchange server to use.
I would recommend using the user impersonation along with autodiscover v2 for the most secure and most flexible setup.

How to handle all user's data through google workspace app

I have been working on a c# application which performs gmail operations on a domain of users. What I am currently doing is using a service account to impersonate users using domain wide delegation. I am able to use the google admin directory sdk to get the list of user emails in the domain in order to impersonate the users. I then use the gmail API to perform account operations on the impersonated user.
To do all this I have to:
1a) manually install the json credential file for the service account
2a) enable domain-wide delegation
3a) enable the appropriate scopes to allow api calls for gmail
I am able to see instances of other applications which have the following flow:
1b) Login to super admin google account
2b) Using the workspace marketplace, perform a domain install to install an application for all domain users.
3b) Launch the app, which redirects to the applications web app.
I noticed that after the application redirects, they are able to access all data for all user's in the domain. From what I understand, installing the app allowed (2a) and (3a) to occur. So the proper scopes were set and the app is usable throughout the entire domain. My question is how are other applications able to achieve accessing all of the data without having to download a credential file for the service account (1a).
From what I gathered, the only way to iteratively access each user's data, you have to use a service account. So once the application redirects, how are they able to access all of the user's data without setting up a service account and how are they able to able to authorize a service account without manually downloading the service account credential file.
I found an video example of a third party app with this flow here:
https://youtu.be/WBNt38b7dQg?t=201

Grant daemon process access to read user mail

We have a console app that we want to run on a schedule in the context of service_account1.
The app needs to access Outlook account for service_account2 using Graph API and read incoming emails.
I am trying to figure out the way to access service_account2 mailbox without requiring user intervention and skipping the consent screen.
One option I see is to manually get authentication code from /authorize endpoint by signing in as service_account2 and consenting to mailbox access by the application. This will give me the authentication code that I can use to get access_token and refresh_token programmatically and that would do the trick.
Is there a way to programmatically do it without having this initial manual step?
For daemon process/console app where you don't want user to explicitly sign-in, you can use client credentials grant.
You can create an application in Azure AD for your process and then use clientid and client secret to access the required resources. For mailbox your resource would be something like /users/{userPrincipalName}/mailfolders/inbox/messages under the graph api.
Here’s a sample for client credentials grant flow from daemon app - https://github.com/Azure-Samples/active-directory-dotnet-daemon/blob/master/README.md
Specifically for avoiding an explicit consent part see steps 9, 10 under this link - https://github.com/Azure-Samples/active-directory-dotnet-daemon/blob/master/README.md#step-2--register-the-sample-with-your-azure-active-directory-tenant.
Steps refer to 'TodoListService' as sample api, but in your case it will be graph I suppose.
Configure Permissions for your application. To that extent, in the
Settings menu, choose the 'Required permissions' section and then,
click on Add, then Select an API, and type TodoListService in the
textbox. Then, click on Select Permissions and select 'TodoListAdmin'.
This will allow this client app to access the service app using
TodoListAdmin role.
At this stage permissions are assigned correctly but client app is a
daemon service so it cannot accept the consent via UI to use the
service app. To avoid this situation, please click on "Grant
permissions" which will accept the consent for the app at the admin
level.
Late answer but it may help someone. I had a similar situation where I wanted to use a daemon to read from a shared mailbox but admins in my organization were not allowing the Mail.Read permission because of its capabilities to read from all mailboxes. I had to restrict the app to only one mailbox to get the consent from admin.
There is an option to scope the application permission to specific mailbox. This ensures that you are not reading from any other mailbox but only the ones you are allowed to. I used the client credential flow in my daemon.
Check the documentation here - https://learn.microsoft.com/en-us/graph/auth-limit-mailbox-access

Outlook REST API - How to retrieve a User Photo

I would like to get the photos of my users from outlook and store them in my database. I want it to be done automatically by the programm with no user interaction required, because i know their email and password.
I´m trying to use this guide:
https://msdn.microsoft.com/en-us/office/office365/api/use-outlook-rest-api#UseaclientlibrarytoaccesstheOutlookRESTAPIGetanaccesstoken
I have already registered my website (.NET MVC 5), but I don´t know how to do the authentication and access token part, because half of the links of the guide don´t work and i can´t find any helpful tutorial / code snippets somewhere else.
I´m deeply grateful for any help.
Instead of using Office 365 REST API, we can use the Microsoft Graph.
And since you don't want to the user participate in the authentication, you can using the Client Credentials Grant Flow which permits a web service (a confidential client) to use its own credentials to authenticate when calling another web service, instead of impersonating a user.
Here is the REST API to get the photo for a specific user for your reference:
GET:https://graph.microsoft.com/v1.0/users/user1#yourdomain.onmicrosoft.com/photo/$value
The app requires one of the following scopes to request the photo of user:
User.Read; User.ReadBasic.All; User.Read.All; User.ReadWrite.All; User.Read
And refer to here to register the app using the Microsoft Graph API.

Getting AccessToken from Azure Ad via UserName & Password

I have a Native Client registered in our Azure AD.
When i'm using
var ar = _context.AcquireToken(resource, clientId, returnUri);
It opens the Prompt for Username and Password. If I enter them correctly I get a valid AccessToken and everything is fine.
When I'm now trying to enter the credentials in code, via UserCrendtial:
var credential = new UserCredential("username", "password");
var ar = _context.AcquireToken(resource, clientId, credential);
But both resulting in an Error when I'm trying it with the directly entered Credentials.
AADSTS65001: No permission to access user information is configured
for '4915f024-blah-blah-blah-f580ab5b0487' application, or it is
expired or revoked.
I have tried the normal (string, string) and the (string, SecureString) overload of the UserCredential.
I have tried it with the exact same combination of username & password, which I have entered in the Prompt, of the first overload from AcquireToken.
I have also tried to give the Application in Azure all the Delegated Permissions:
Read directory data
Read and write directory data
Access your organization's directory
And added Windows Azure Service Management API Application with Permission:
Access Azure Service Management
Nothing helped.
As a sidenote, the Application in the Azure has permissions to a SharePoint O365 Tenant. To Read and Write ListItems I don't know if this is relevant. The Resource i'm passing through is the SharePoint Adress.
I don't need any user access over the Graph Api to the Azure. I only need that AccessToken to access our SharePoint Online.
Edit:
Architecture:
Description:
We have a Web Api Project which handles the User Authorization, Load Balancing etc. This Web Api Project, will be queried by either Native Dekstop Clients or Hybrid HTML5 & Javascript Mobile Device Apps.
The Web Api Project needs to Read, Create, Update & Delete Data from our SharePoint O365 Tenant. So this where I need the AccessToken to init a ClientContext or send i via a rest response.
Since the Web Api handles the User authorization, there is an endpoint for users to login already and in this endpoint I want to acquire the Token. That's why I want it to be silent, because the "flexbile browser popup" is already there.
Maybe I don't need in this scenario the Token acquiring with Username / Password, but then I don't know how to configure the Azure App right to work with all the different native client's.
not sure if it's your case but you can use :
built in auth (setting 'on' in webapp options; then create express app or/and then chose advanced mode with same apps ids);
then add AD native client app;
login to old classic portal there select native app and in config add access to you express/advacsed web app;
after that you will able login in browser; and with adal lib will able login to access you api from mobile devices;
for more see ms docs and samples;
The direct use of username and password has important limitations, please make sure you are not stumbling on any of the ones listed in http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/.
Also note, nothing that requires displaying a user consent screen (as all the permissions you described will) or specific disambiguation steps (like trying to use a guest user from X to access a resource protected by tenant Y) will work.
What is your scenario? Any specific reason for which you want to use username/password instead of the more flexible browser popup?

Categories