Access denied when using OAuth client credentials flow to create shared mailbox

985 Views Asked by At

Short version:

How to correctly set up application permissions and/or role assignments and/or something else that I'm missing, so that application id/secret (OAuth client credentials) can be used to create shared mailboxes?

So far I've tried couple combinations of permissions/roles, e.g. Exchange.ManageAsApp with User Administrator (fe930be7-5e62-47db-91af-98c3a49a38b1), Exchange administrator (29232cdf-9323-42fd-ade2-1d097af3e4de) and bunch of other.

Details:

I have a bunch of powershell scripts used to automate various tasks on Exchange Online. So far I've been using basic auth, which I was able to successfully convert into OAuth password flow.

But to get rid of dependency on service account completely, I'd prefer to use credentials flow. In background I'm trying to do something like this:

var authenticationContext = new AuthenticationContext($"https://login.microsoftonline.com/{TenantId}", false, _tokenCache);
var clientCredential = new ClientCredential(ClientId, ClientSecret);
var authenticationResult = await authenticationContext.AcquireTokenAsync(Resource, clientCredential);
var username = "OAuthUser@" + TenantId;
var password = authenticationResult.CreateAuthorizationHeader();
var executor = new ExolExecutor(username, password);
await executor.Execute(Script, cancellationToken);

where executor does the regular thing:

  1. Create PSSession to https://outlook.office365.com/powershell-liveid?BasicAuthToOAuthConversion=true
  2. Executes powershell script using
    using PowerShell powershell = PowerShell.Create();
    powershell.Runspace = runspace;
    powershell.AddScript(script);
    ...
    await Task.Factory.FromAsync(powershell.BeginInvoke(input, output), powershell.EndInvoke);
    
  3. Remove PSSession

So far so good. Works perfectly fine with Get-Mailbox -ResultSize 1. But when trying to create new shared mailbox New-Mailbox -Name "pko222" -DisplayName "pko222" -Alias "pko222" -Shared, I'm getting

CategoryInfo.Activity: New-Mailbox
CategoryInfo.Category: 1001
CategoryInfo.Reason: ADOperationException
CategoryInfo.TargetName: 
CategoryInfo.TargetType: 
ErrorDetails.Message: 
ErrorDetails.RecommendedAction: 
Exception.Message: Active Directory operation failed on DB7PR01A03DC005.EURPR01A003.prod.outlook.com. This error is not retriable. Additional information: Access is denied.
Active directory response: 00000005: SecErr: DSID-03152612, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0

FullyQualifiedErrorId: [Server=BEXP281MB0087,RequestId=88419a8e-78a4-4967-9bca-71d40feb5150,TimeStamp=10/6/2020 11:57:38 AM] [FailureCategory=Cmdlet-ADOperationException] 2C0312E5,Microsoft.Exchange.Management.RecipientTasks.NewMailbox

JWT token looks something like this:

{
    "aud": "https://outlook.office365.com",
    "iss": "https://sts.windows.net/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/",
    "iat": 1601985127,
    "nbf": 1601985127,
    "exp": 1601989027,
    "aio": "E2RgYFCOsw1iZj34elV49CH5zyd5AQ==",
    "app_displayname": "XXXXXXXXXXX",
    "appid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "appidacr": "1",
    "idp": "https://sts.windows.net/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/",
    "oid": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
    "rh": "0.AAAAv9y4fwZQ_0G6_d1kLKJ_sarAXb_REQFHhc2EM1FNn9tIAAA.",
    "roles": ["User.Read.All", "full_access_as_app", "Mail.ReadWrite", "MailboxSettings.ReadWrite", "User.ReadBasic.All", "Mailbox.Migration", "Mail.Read", "Mail.Send", "MailboxSettings.Read", "Exchange.ManageAsApp"],
    "sid": "qqqqqqqq-qqqq-qqqq-qqqq-qqqqqqqqqqqq",
    "sub": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
    "tid": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
    "uti": "CRytfXbD80y3ATmQvd-VAQ",
    "ver": "1.0",
    "wids": ["29232cdf-9323-42fd-ade2-1d097af3e4de", "88d8e3e3-8f55-4a1e-953a-9b9898b8876b", "fe930be7-5e62-47db-91af-98c3a49a38b1", "9360feb5-f418-4baa-8175-e2a00bac4301", "62e90394-69f5-4237-9190-012177145e10", "0997a1d0-0d1d-4acb-b408-d5ca73121e90"]
}
1

There are 1 best solutions below

0
On

Fyi i managed to make it work on my side. you just need to add the following param in the connection uri

&email=SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@yourtenantname.onmicrosoft.com

so the connection uri looks like :

https://outlook.office365.com/PowerShell-LiveId?BasicAuthToOAuthConversion=true&email=SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@yourtenantname.onmicrosoft.com

just change the suffix from 'yourtenantname' with ... your tenant name! dont put the tenant guid !

https://learn.microsoft.com/en-us/answers/questions/451006/pssession-and-modern-auth.html