How to check Exchange the Application Impersonation Permission of a meeting resource by EWS managed API? - exchange-server

I want to get the calendar information of the meeting resource by an Application Impersonation account.
I need to check if the Application Impersonation account has permission to get the calendar information from the meeting resource.
(As I know the meeting resource can be set to refuse the access by the Application Impersonation account)

You can't do what you want using EWS as the only way to check the underlying permissions would be to use the Exchange Management Shell cmdlet. However the easiest way is just process the result of EWS operation you make eg with the EWS managed API if you don't have impersonation rights then you will received an error which will indicate that you don't have Impersonation rights. eg
try
{
//EWS request
}catch(Exception Exception)
{
if(Exception is ServiceResponseException)
{
switch (((ServiceResponseException)Exception).ErrorCode)
{
case ServiceError.ErrorImpersonateUserDenied:
break;
case ServiceError.ErrorImpersonationDenied:
break;
case ServiceError.ErrorImpersonationFailed:
break;
}
}
}

Related

EWS managed API: Is user A able to impersonate User B in a windows app?

I need to determine whether domain UserA -- currently running a Windows desktop application -- has permissions to impersonate another user in Exchange, say UserB.
I can try to do something like read UserB's inbox messages, but I was after a cleaner way to do it.
Is there no way to load the UserA's Exchange roles and look for ApplicationImpersonation or something else?
So the setup is like this:
ExchangeService service = new ExchangeService(exchangeVersion);
service.UseDefaultCredentials = true;
service.AutodiscoverUrl(userEmail);
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, UserToImpersonate);
// Looking for something like this:
if (!service.CanImpersonate(userEmail, UserToImpersonate) )
{
Exception ex = new Exception(userEmail + " can't impersonate " + UserToImpersonate);
throw ex;
}
Not using EWS you would need to use the Exchange Management Shell cmdlets https://learn.microsoft.com/en-us/powershell/module/exchange/role-based-access-control/get-managementroleassignment?view=exchange-ps to check if applicationimpersonation is enable for a particular user. EWS is a Mailbox API and the setting your talking about is an administrative setting so the best you can do with EWS is deal with the exception and suggest corrective action.

Using streaming notifications with delegate access

So far all information that I read about streaming notifications says that you are expected to use impersonation with streaming subscriptions when you want to subscribe to not your mailboxes. This sounds reasonable when you have service application that accesses user mailboxes. In my case I need to subscribe to calendars of room mailboxes.
Based on this answer: Getting notification from Resource calendar in EWS room mailboxes usually have their account disabled and I need to use delegation.
So what is proper way to subscribe and maintain affinity when using delegation? Should I just ignore setting the impersonation header and do everything else as described in How to: Maintain affinity between a group of subscriptions and the Mailbox server in Exchange?
When you creating folder object, pass the other user email address which shared his calendar with you. AS below
folders[0] = new FolderId(WellKnownFolderName.Calendar, new Mailbox("OtherUserEmail"));
And then subscribe.
service.SubscribeToStreamingNotifications
For resource rooms I use impersonation as the preferred access. I know that in general the AD userids for room resources are disabled for login in AD, but my guess is that affects only Windows login. Technically when you impersonate, you don't really login as the room user. You log in as the service account with those credentials, and then indicate with the impersonation id that you want Exchange to pretend it's actually the room making all the requests you are about to make.

Gmail API domain-wide delegation

I am using Gmail API and I am trying to fetch emails from all users under company. But when I run code such as:
function runAPI(auth) {
var gmail = google.gmail('v1');
gmail.users.threads.list({auth: auth, userId: '108800016305523828361'},'',function(err, response){
if (err) {
console.log("The API returned an error: " + err);
return;
}
var threads = response.threads;
console.log(threads);
})
}
I get error:
The API returned an error: Error: Delegation denied for xxxx#xxxxx.com
In admin console I did this:
As client name I used id from the client_secret.json file. And for scope, I gave it all permissions.
How do I properly setup domain wide delegation for Gmail API ?
The setup is fine, however in your code you're doing it wrong.
This code:
gmail.users.threads.list({auth: auth, userId: '108800016305523828361'},'',function(err, response)
specifically.
userId should be "me" however before you can call the Gmail API you need to use the service account "JWT flow" in your code to retrieve an oauth2 credential for the Gmail user you want to access as described in the Preparing to make an authorized API call service account domain-wide delegation doc.
Specifically this uses your service account's private key to request to get a credential for the user you desire (set the user's email in your domain that you want to access in the setServiceAccountUser(user#example.com) function in the request). Then you can use that GoogleCredential in your call to the Gmail API.
For the question How do I properly setup domain wide delegation for Gmail API?
I think this documentation from Google can help you with this, just follow this steps to delegate domain-wide authority.
Go to your Google Apps domain’s Admin console.
Select Security from the list of controls. If you don't see Security listed, select More controls from the gray bar at the bottom of the page, then select Security from the list of controls. If you can't see the controls, make sure you're signed in as an administrator for the domain.
Select Show more and then Advanced settings from the list of options.
Select Manage API client access in the Authentication section.
In the Client Name field enter the service account's Client ID. You can find your service account's client ID in the Service accounts page.
In the One or More API Scopes field enter the list of scopes that your application should be granted access to. For example, if your application needs domain-wide access to the Google Drive API and the Google Calendar API, enter: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
In your case, use this scope for Gmail API.
Click Authorize.
For more information about the error 403 or Delegation denied for <user email>,check this related SO question:
Gmail API returns 403 error code and “Delegation denied for user email"
GMail API Super Admin access other users accounts via API?

Access ExtendedProperties on resources that do not belong to logged in user

TL;DR version
Is there any way to access ExtendedProperties on a resources that does not belong to the logged in user from an Outlook add-in?
Detailed version
We are setting ExtendedProperties on a CalendarFolder associated with a resource. We tried to access these ExtendedProperties from our Outlook add-in, however, since the CalendarFolder does not belong to the logged in user, the Outlook JavaScript API returned with an error when we used: mailbox.makeEwsRequestAsync()
Office extension have no permissions to access any other mailboxes
then the mailbox provided in the user context
The logged in user does have owner permissions on the CalendarFolder for the resource (Set-MailboxFolderPermission -Identity RoomResource#domain.com:\calendar -User admin -AccessRights Owner)
We are able to access the ExtendedProperties as expected when we create a simple console app and use the .NET Managed API, so we figured we could call the same EWS endpoint (/EWS/Exchange.asmx) from our add-in.
We first get an access token (using mailbox.getUserIdentityTokenAsync) and pass that with our call to the EWS endpoint directly from our add-in.
When we make an AJAX call to that endpoint, we are getting a 401 Unauthorized response from Exchange with the header:
x-ms-diagnostics:2000001;reason="The callback token is missing one or more expected claim types.";error_category="invalid_token"
Question
Is it possible to call the /EWS/Exchange.asmx endpoint on Exchange (on-prem and online) using oAuth? If so, how can we get a valid token that will validate. Can we ask for additional claims when requesting a token?

Integrating Exchange with website

We are trying to integrate Microsoft Exchange (sync appointments) into our web site (SPA)(Software as a Service), for this we are looking at EWS managed API as the preferred route, we have the end users email, but we do not want to store there exchange passwords (as they are generally same as users domain password), in such a scenario which is the best approach to take. Please Help.
The preferred way would be to define a new Exchange id for your integration program and allow it impersonation rights for each user whose mailbox you want to examine. The managed API will allow you to specify an impersonation id on each call. You authenticate with your program's userid and password, but have the rights within the Exchange store of the user you are impersonating. Thus you only have to manage a single password for your program and need not know users' passwords. Setting up the impersonation rights requires some fancy PowerShell commands from the Exchange Admin, but you only do it once.

Resources