I have an automation project (.NET Framework) which currently makes use of Microsoft.Exchange.WebServices to easily do simple tasks like finding email in a remote inbox or folder, checking for attachments etc. We grab the data from an organisation email account on: outlook.office365.com
Recently I have embarked on rewriting my project in .NET Core and this has presented a number of problems including my continued use of EWS:
Today we are sharing our plans to move away from Basic Authentication access for EWS over the next two years, with support ending Oct. 13, 2020.
https://techcommunity.microsoft.com/t5/exchange-team-blog/upcoming-changes-to-exchange-web-services-ews-api-for-office-365/ba-p/608055
Microsoft Graph is the recommended API to use for accessing Exchange Online data. New applications designed to access Exchange Online data should use Microsoft Graph.
EWS support also seems low within .NET Core various warnings appeared in the project after installing.
All my current work with EWS is done in a class with a couple of environment variables being passed to setup the WebCredentials etc. but as I have read through a number of Microsoft articles (including: Get access without a user) I have realized nothing will be simple anymore :) on the usage of Graph I have found no straight forward code examples of how to implement this purely back end integration into a mailbox in the simplest possible way.
I'm wondering if someone could give me a simple and appropriate Authentication and authorization example relevant to a back end integration? i.e. one without Administrator consent pop ups or any other pop ups that would not be appropriate to an integration like this, is this still possible?
Here's a net core 2.1 console example
There are Delegated and Application permissions. Delegated is a popup, and requires a user, application is via a service principal (and can be done non-interactively/in automation).
Step 2 in the above example uses the User.Read.All permission. That gets you email address, as well as a bunch of other information about your users. It's way overkill if you just want email. User.ReadBasic.All is a much better permission to put on the app registration for your purposes.(The example should work fine with you changing the permissions to User.ReadBasic.All)
In the last part of the example (pasted below), you'll want to change the query and most likely want to add an iterator.
GraphServiceClient graphClient = GetAuthenticatedGraphClient(config);
List<QueryOption> options = new List<QueryOption>
{
new QueryOption("$top", "1")
};
var graphResult = graphClient.Users.Request(options).GetAsync().Result;
Console.WriteLine("Graph SDK Result");
Console.WriteLine(graphResult[0].DisplayName);
Graph and MSAL may seem complicated at first but are very valuable. Microsoft is adding functionality (and functions) to graph regularly. Graph 1.0 Docs
Related
I have been successfully using the Office 365 unified API to link my multi-tenanted SaaS application to Office 365 and return files for unified groups. I am achieving this using the ADAL library and Unified API nuget package. We have requested the following permissions (among others) in our Azure AD application as per the Unified API preview release notes - Group.Read.All, Group.ReadWrite.All, Sites.Read.All, Sites.ReadWrite.All. I appreciate ReadWrite makes Read unnecessary but we have added both sets to try and protect ourselves from some of the possible preview issues.
Now we have a tenant who can read their groups but cannot access the files in the group. This works fine in other tenants.
When we debugged the code, we found that this line was throwing a null reference exception:
IPagedCollection<IItem> files = await _client.groups.GetByID(groupId).files.ExecuteAsync()
We then separated it out to check the group was being received OK which it is:
IGroup group = await _client.groups.GetById(groupId).ExecuteAsync()
We therefore made the same files request using HTTP client so that we could get a more detailed response from the server:
https://graph.microsoft.com/beta/myOrganization/groups/[group_id_here]/files
This is returning a status code of 500 - internal server error and the content is 'Object reference not set to an instance of an object'. Not very helpful!
I've seen a few threads about people experiencing similar issues with permissions not being setup correctly but in my case I can't understand why the call to retrieve unified group files will work fine in one Office 365 tenancy but not in another when their privileges are controlled by the same Azure AD Application and are therefore exactly the same.
The groups are all being created in the Office 365 Web App, not via the Unified API so that isn't a factor.
Are there permissions in Office 365 that admins can use to restrict access to unified api requests? I can't see anything in the documentation, but even if that were the case I would expect an unauthorized response instead of internal server error.
Any ideas much appreciated!
Sorry for this issue. So I believe that we accidentally pushed a change early and you managed to hit this before we reverted the change. We're in the process of updating access to files through OneDrive APIs, which will cause a breaking change. You can read more on this, and the breaking that on the /beta endpoint that we plan to update on 10/19, here: http://dev.office.com/blogs/Update-2-on-Office-365-unified-API. After the update, accessing files will require this syntax:
https://graph.microsoft.com/stagingBeta/microsoft.com/groups/groupId/drive/root/children
NOTE: We'll need to generate a new client library for this. The one you are currently using will break with this update. We hope to get a new client library out very soon after this service update.
Now I'm not sure if this is exactly what you stumbled upon or whether this is a different issue. Can you try it again (before we make the update on 10/19 at 12pm PDT)?
Hope this helps,
I am using Azure Active Directory as a base for security/permissions to a Sharepoint 2013 portal. I developing an administration UI using Graph API to load and edit data from the Azure Active Directory. The setup also includes Exchange Online, such that each user defined in the system will be given a mailbox in my domain. The Groups and Users in the Azure Active Directory are synced to the Sharepoint 2013 and Exchange Online using DirSync.
The plan is to use the administration page to consolidate certain expected actions, including creation of new users, connect them to the relevant security groups, as well as creating new mail-enabled security groups.
As is described in the Graph API Group Overview, only "pure" security groups are allowed to be created. Further more, the Graph API does not allow the mailEnabled field to be updated to true after creation... In fact, the Azure Active Directory management screen is so limited that a mail-enabled Group cannot be created there either (or am I missing something?).
I am trying to find a solution that will let me still to consolidate all of the actions that I wish to allow under one administration application.
It seems that PowerShell might be an option, though I am not exactly well-versed in using PowerShell.
I have tried to find an API that would allow me to connect to Exchange Online and perform similar actions - DirSync seems to sync everything from there to Azure Active Directory just fine - I create a mail-enable security group in Exchange and I get a mail-enabled security group in Azure Active Directory moments later - I have not been able to find such an API. Does it exist?
Am I looking at it all wrong? Is there a simply solution to my needs as stated above that I am simply not aware of?
Doesn't sound to me like you're missing something. The thing is, mail-enabled security groups only make sense if you have something providing the "mail". For Microsoft's online services, this would be Exchange. Azure AD and "pure" security groups apply everywhere, but one could argue mail-enabled group only applies if Exchange is in the picture. Anyway, that's an attempt to explain the why.
As to programmatically accessing Exchange, you have many options (see Exchange Online and Exchange 2013 development (in no particular order):
a) Exchange PowerShell cmdlets
Exchange allows you to programatically create and manage distribution groups with the Exchange Online PowerShell cmdlets. For example, the New-DistributionGroup cmdlet:
New-DistributionGroup -Name "My Favorite People" -Type "Security"
As you've noticed, these groups will be synced back to Azure AD as read-only. You can then use them (for example) with Azure AD Graph API to do RBAC based on group membership.
a.1) Exchange PowerShell cmdlets run from C# code
If you want to run these cmdlets from other .NET code (e.g. C#), it is doable. Take a look at the example in How to: Get a list of mail users by using the Exchange Management Shell. It can easily be used to get/set groups instead of users.
b) Exchange Web Service and EWS Managed API
Your best bet at this point might be to use EWS Management API:
Get started with EWS client applications
Get started with EWS Managed API client applications
c) Office 365 API (although this scenario is not currently supported)
Keep an eye on the Office 365 API, which doesn't look like is support this scenario yet, but looks promising: http://msdn.microsoft.com/en-us/library/office/dn605892(v=office.15).aspx
I am working with an asp.net application in .net 4.0. I have configured it to use windows integrated authentication.
What I want it to do is use the user groups on my pc/server as if they were roles. I can't find documentation or mention of it anywhere from my google results.
The reason this is required is because we have a COTS product which does this and we want to reuse the groups as roles.
Could I get an example or a pointer to some documentation so I can figure out how to do it?
The end result here was that we communicated with our Sever Services team who were more than happy to help us use Active Directory to come up with a Corporate solution instead of using individual server user stores. This is a much better solution as the groups are reusable and integrate with other applications too.
The lesson here is that engagement with IT services with a business case is always worth the effort.
I’m working on getting data sync happening for my Win8/WP8 app - written in XAML/C#. Periodically / or at app start up / suspend, I want to sync data files with the user’s OneDrive. To do that I need to get them to login to their Microsoft Live Account. I was looking to use Live SDK (v5.6) to do that.
Problem:
For users who have local Windows 8 accounts, the Live SDK lets me sign then in with a built-in credential prompt. This is working.
For users who have linked their Microsoft account with their Windows 8 account (and are logged in to Windows using their Microsoft account) the Live SDK lets me use single sign-on - and I have this working.
But I can’t call sign out, in order to sign in with a different Microsoft account.
1b is my problem. The built-in Windows Store app, lets users have a UX where they can use the MS account linked to their Windows account - OR - choose to use a different MS account. In effect: a ‘sign in as different user’ option. (See attached). It doesn’t look like it is technically single-sign-on in the built-in Windows store app, but that’s the UX I want - I don’t care so much for single sign-on, its a nice to have, but sign-in as a different user is a very important requirement.
What I’ve tried:
Lots of searching around. Found a bunch of people on the interwebs asking for the same thing. There are unanswered questions and even some ‘accepted’ answers on SO that don’t really work:
Sign in to multiple Microsoft account in Windows Store app
Windows Live SDK doesn't LogOut()
(incorrect answer)
Can the Windows 8 Live SDK use another Microsoft Account other than the current user? (incorrect answer)
I’ve forked the LiveSDK on Github (https://github.com/krishna-nadiminti/LiveSDK-for-Windows/commit/2cdb5408c0d8482c026cd96da6b99e4633677081) and tested it out - with and without requesting the ‘wl.signin’ scope - no good. It doesn’t have an option to change user.
Looked through the docs for WinRT - OnlineIdAuthenticator class, there is an option to always show CredentialPrompt when signing in users - but it does not allow the user to change the username if signed in via a linked account.
I looked through the built-in WinStore app’s js code and it uses some internal (native?) call to a ‘OMStub’ - which has methods to auth the user. This doesn’t seem to be part of the public JavaScript Live SDK
Question(s):
Are there Win32 / WinRT APIs that I could use to show credential prompts in a XAML app?
Can I use a WebView and auth users that way?
Should I just fall back to using the REST API and roll my own auth flow + UI for this?
How does the WinStore app do it?
Workarounds / Store certification:
For now, I’m a bit worried I only have the last option: roll my own .NET client over the Live connect REST API, and add my own UI for the credential prompt, and a user consent dialog which look exactly like the ones that the Windows Runtime provides. What will happen to store certification in that case? I can run it past WACK first - but the store app cert guidelines don’t talk about this: so unsure whether it will pass certification.
There is no mention of Microsoft account that I could find in the app certification guidelines.
The docs for Live SDK on MSDN explicitly mention that we’re not meant to create our own login UI: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh968445.aspx
However, the store app seems to violate this - may be because it doesn’t use the Live SDK at all.
There is also a MSDN article that says when the user signs in to Windows with a Microsoft account, sign out is just not possible from inside an app:
http://msdn.microsoft.com/en-us/library/windows/apps/jj193591.aspx#adding_user-authentication_functionality_to_your_windows_store_apps and that the only way is for the user to dissociate the Windows/Microsoft account or switch to a different user account.
Again - clearly this is not the case. The store app provides users a way to use a different account.
Help please?
You might want to look into the Web Authentication Broker: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/dn448945.aspx
It will invoke the actual Microsoft Account login flow but still give you the flexibility to sign out and back in as another user.
The project I'm working on is a set of tools for users to manage their own accounts. For example, generic users will be able to access and update their Drive or calendars, and for administrators they can additionally get lists of their users and groups and manage those.
My concern is the API limits. At this point in time the project's client ID and secret are hard-coded because I want users to just be able to download and run the tools (which is working great until someone queries all users and uses up half of the daily limit for one of the APIs). I realize I can request more API calls, but I'm not sure that's the best solution.
In order to have each user on their own API limits, will I need to have each person using it set up a new Google Code project with its own set of limits? Or is there a way to allow the same project to have limits based on domain? I'm not sure what best practice is.
Edit: I should mention I'm authenticating via OAuth2.0 using 2-legged authentication, as my understanding was that was the best way to do it for administrators and users... should I be using 3-legged instead?
This is (probably) not an answer, but ...
A good question is precisely what is an "app". In this answer What is the limit on Google Drive API usage?, Nivco from Google says "Currently for the Drive API it reads "Courtesy limit: 10,000,000 queries/day". It's a per app quota"
and on the API Console, your project can consist of many "apps", each with its own client ID.
So, either (a) the term "app", being ill-defined, is being used incorrectly, or (b) you can achieve what you are looking for by creating multiple apps within your project.
Sadly, I suspect it's (a), but might be worth confirming.