Access Outlook office mailbox(mails in inbox) using python code through EWS - python-3.x

I was reading the Outlook mails through EWS using python exchangelib module
credentials I was using for authentication: email & app password
Due to some security reasons the platform team have disabled the App password feature and I ended up accessing the mail box as am not sure how to access mail box without App password ???
If there is any alternative to App password please suggest me..
Note: My python script was running in Linux VM

When you use an email & app password this is using Basic Authentication which is why your platform team has disabled it. You need to move to using oAuth https://ecederstrand.github.io/exchangelib/#oauth-authentication and make use of the client_credentials flow https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow. So you then use a client secret or certificate rather then username & pword. When using this flow you need to make sure you impersonate the Mailbox your trying to access and also don't use Autodiscover because that will fail with that flow. By default this will give you access to all mailboxes in a tenant so if this is a problem you can scope it down to just the mailboxes you need to access https://techcommunity.microsoft.com/t5/exchange-team-blog/application-access-policy-support-in-ews/ba-p/2110361

Related

Is possible to retrieve data and download files from outlook without password using ExChangeLib (EWS)?

I'm trying to access data from Outlook and can download files from exchangelib with a password. But I'd like access without a password. Do we've any alternate for this stuff?
An alternative to "this stuff"? Meaning an alternative to security? No.
The best you can do without credentials is to use Outlook Object Model on a machine where Outlook is already installed and configured to access the folders and messages from a mailbox in the configured local profile.
You cannot use exchangelib to connect to the Exchange server without credentials of some sort, but exchangelib supports a variety of auth methods, and not all credentials contain a password. OAuth uses tokens, Kerberos and SSPI use a security context already available in your Windows session, certificate-based auth uses an on-disk file AFAIK, etc.

authenticating a backend server with oauth but the server is on a private VLAN

I am trying to authenticate a backend server with OAUTH in order to send emails from that backend server. The thing I don't understand is how can I do this if the server will only ever be run locally on a VLAN.
Is this even possible?
What I am currently doing:
Backend server (Running Node) uses Basic Authentication credentials (username & password) to authenticate then send an email through Office 365 account to a user using SMTP. Basic auth is being deprecated though and is being replaced by OAUTH.
What I want to do:
Replace basic authentication with OAUTH to authenticate and send emails from backend server through office 365 account.
Any help would be greatly appreciated.
The usual migration path here is Client Credentials Flow which should work like this:
Back end on private VLAN must be able to make outbound calls to the Authorization Server (Azure AD in your case).
The advantage should be that the credential is not revealed every time you want to send an email, and OAuth access tokens are used instead.
This should work in locked down environments where outbound calls are restricted. Usually a whitelist is configured in the firewall - eg all URLs other than Azure AD are blocked.
This is specially for how to implement it using Azure Active Directory & Office365 as the E-mail sender, but the main ideas for how to implement this should work for other services. The only caveat is that some other services will require you to obtain an accessToken first and use that in conjunction with their API.
Using the information about Client Credentials Flow provided by #Gary Archer
combined with the Microsoft Graph SDK
as well as examples for how to:
Register an app in Azure
How to Create a Client
Get ID of User by fetching user data
How to send Emails
I was able to figure this out.

Signing into my Gitlab CE installation with my app's login

I have a nodejs webapp with many users with a custom login process. I would like gitlab to accept that authentication and not force users to create a new app. What is the best way to accomplish this?
I would go for OAuth 2.0 Single Sign On (SSO). Below you can find the architecture diagram taken from here. As you can see the client is redirected to log in in the OAuth2 provider to get a valid token for authentication. The OAuth2 server must be configured for the application requesting access including the secret, the client id and the callback URL.
You can configure GitLab CE to sign in with almost any OAuth2 provider. Only be careful with the limitations:
It can only be used for Single Sign on, and will not provide any other access granted by any OAuth provider (importing projects or users, etc)
It only supports the Authorization Grant flow (most common for client-server applications, like GitLab)
It is not able to fetch user information from more than one URL
It has not been tested with user information formats other than JSON
You also need to configure your node js web application as an OAuth2 server. There are npm availables with the source code here.
Recommendation
I would install some open source Identity Management to separate the user management from your webapp, provides better integration with other third parties and forget about encryption and other stuff you need to take care in your webapp. There are multiple options such as KeyCloak for instance.
You have to define a dedicated user , and use the private_token of this user to login for ALL users that will use your application.
The restricition would imply all users will have the same rights ....
The other solution is to use the Private Token of the user at login. In this case , only the rights of these particular users will be used.

Exchange Web Services are not currently available for this request because none of the Client Access Servers in the destination site could process

I am using EWS Java APIs and passing OAuth tokens to fetch data from office 365 mailboxes.
Because I am developing Web APIs I preferred using "Application Permissions" defined in Azure active directory application for Office 365, and used "client credential flow" OAuth flow to fetch OAuth token specific to application which will allow "Have full access via EWS to all mailboxes in the organisation".
After fetching token with the procedure specified in the document "http://blogs.msdn.com/b/exchangedev/archive/2015/01/21/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx"
I passed this token to EWS Java APIs,
it gave me error saying:
microsoft.exchange.webservices.data.ServiceResponseException: Exchange Web Services are not currently available for this request because none of the Client Access Servers in the destination site could process the request.
I tried similar thing with EWS managed APIs for .net. Got similar error.
Can anyone provide some help and direction to resolve this error.
Thanks & Best Regards,
Pranjal
I was able to resolve the issue, by simply adding following line of code
service.getHttpHeaders().put("X-AnchorMailbox","smtpemailaddress");

Oauth2 for SharePoint 365 REST

I'm trying to connect to Sharepoint Online (Sharepoint 365?) content using OAuth2 and the REST API. I need to do this from Python as it is an addition to an existing application. I have already managed to connect the application to Google Drive using OAuth2 and REST, so I think I understand the fundamentals of using OAuth2.
I've tried a number of combinations of places to configure the client_id and client_secret and authenticate and receive access and refresh tokens.
So far I have been able to receive a refresh token and use it to obtain an access token; however, I'm unable to use the access token to access content on the Sharepoint 365 site.
For configuring the client_id and client_secret I associated my Sharepoint site with AAD using the Azure Management Portal. Then I added an application to the Sharepoint AD entry with the client_id and client_secret. In Sharepoint I used appregnew.aspx to register the client_id and verified the application appears in appprincipals.aspx.
I call the authentication service using:
.../login.windows.net/common/oauth2/authorize?api-version=1.0&response_type=code&client_id=&redirect_uri=&resource=Microsoft.Sharepoint
and am able to authenticate, receive a code, call back to
.../login.windows.net/common/oauth2/token with the code and receive access and refresh tokens.
I serialized those tokens and from a separate process call
.../login.windows.net/common/oauth2/token with the refresh_token, client_id, client_secret, and grant_type=refresh_token and receive a new access token.
Finally I call in to Sharepoint service endpoint
-my.sharepoint.com/personal//_api/web/files'
with the new access token and it fails telling me the resource Microsoft.Sharepoint is invalid (Invalid audience Uri 'Microsoft.SharePoint')
I've been spinning my wheels trying various permutations of where the client_id is configured and this is as far as I've gotten. Since all the documentation and examples seem to depend on using C# libraries such as TokenHelper I feel like I'm missing something key but simple and can't find the required information.
Has anyone connected to Sharepoint Online using Python, Ruby, Java, etc? If so:
Where should the client_id be configured?
What are the endpoints for obtaining the refresh and access tokens?
What is the appropriate audience uri or resource for which to request tokens?
Many thanks!
I've successfully connected to SharePoint Online using PHP. It looks to me like you're combining two different methods to do so.
Here is what I did:
Register my app in Azure AD on the Management Portal to get client_id, client_secret, redirectUri and the right permissions on Office 365 for sites.
Call the authorization endpoint at https://login.microsoftonline.com/common/oauth2/authorize
Call the token service endpoint at https://login.microsoftonline.com/common/oauth2/token
Call the SharePoint REST endpoint with the access token.
The resource should be simply the URL of your SharePoint site.
The appregnew.aspx and appprincipals.aspx pages are used for apps for SharePoint but it doesn't look like you're building one.
I think you are trying to do OAuth from Sharepoint Online without creating an Add-In inside Sharepoint. This was the exact problem I was facing. I know this is an old question but my answer might be helpful to someone else coming here.
It is possible to do OAuth from any web-app. Here are the step by step instructions in my blog -
https://medium.com/#yash_agarwal2/performing-oauth-and-rest-calls-with-sharepoint-online-without-creating-an-add-in-677e15c8d6ab#.6pf4wp83b
High Level overview -
1) Get client id and secret by registering yourself here - https://sellerdashboard.microsoft.com/Registration
2) Get Access Token, Refresh Token by following steps here -
https://msdn.microsoft.com/en-us/library/office/jj687470.aspx
Im probably a bit late to the party, but to whoever stumbles into this one, you can have a look at how the SharePoint Oauth App Client lib does it.
You'll probably want to check the SPSite and SPAccessToken classes.
I know this is old by had to deal with similar problem and have 2.5 solutions.
This solution is specifically for the federated logins.
Simple hacky solutions works like a magic for files :)
On Windows 10 - the silliest solution:
First login to your sharepoint with Internet Exploer/Edge. Must be IE/Edge.
Then in Start-> Run dialog or any Windows Explorer address bar do this: \\<your_sharepoint_site.com>#SSL\rest\of_the\path. Note #SSL after host name.
Make sure to replace all the forward slashes with backslashes.
This makes sure that your login credentials are captured by the system.
Then navigate to "This PC", menu "Computer->Map Network Drive" and paste either that same path from above or your normal URL https://<your_sharepoint_site.com>/rest/of_the/path into Folder text field of Map Network Drive.
Now you have Sharepoint folder mapped as regular network drive X:\! Which allows you to treat is just as normal file system folder from any program or programming language.
This solution uses WebDav WebClient and by default you will hit a 50MB limit! Worry not follow these steps to release yourself from the shackles of the silly limit.
Simple Hacky.
Open your browsers and open the 'Developer Tools'.
Navigate to 'Network' tab of 'Developer Tools'
With Network tab open login to your sharepoint site.
Click on any of the requests and you shall see that every single Request Header has a Cookie with FedAuth=some_very_long_base64_encoded_xml_struct;rtFa=something_else_long.
Basically you need these two cookies FedAuth and rtFa.
Now with every GET POST (curl, wget etc) request to the Sharepoint just add a new header Cookie with the value FedAuth=<fedauth-cookie-value>;rtFa=<rtFa-cookie-value>.
Programmatic-hacky (example in python on windows), essentially #2 but cookie manipulation all done programmatically.
We shall steal the cookie directly from the kid... I mean from the Chrome browser.
Navigate to your Sharepoint With the chrome browser and perform all the necessary login actions.
Steal the cookie gist. Plagiarized from here.
Use the cookie gist.
REST of Sharepoint REST API wisdom here and ref here.
Finally open a beer enjoy your day.

Resources