Azure Graph API возвращает недостаточные привилегии в PATCH одному Azure AD B2 C Tenant, но не другому с той же конфигурацией - PullRequest
0 голосов
/ 17 июня 2020

Введение в проблему

У меня есть два разных Azure AD B2C tenants один для dev , а другой для production . Оба с двумя приложениями: приложение ROPC_AUTH и приложение API .

Оба клиента имеют ROP C User Flow.

Оба клиента имеют одинаковые subscription Id и одинаковые Resource Group.

Я использую эти клиенты для входа , регистрации (с использованием GraphAPI POST ) и Сбросить пароль (используя GraphAPI PATCH).

Все работает нормально для Login и Registration настройки аутентификации и GraphAPI в моем бэкэнд. Однако Reset Password работает только для одной из моих конфигураций Tenant; Я получаю 403. Недостаточно прав для другого.

Конфигурации

Ниже приведены манифесты для двух приложений в обоих клиентах.

Манифест приложения API клиента 1

{
    "id": "581c1a83-ff0c-49ed-8ace-aa5b63e9ea44",
    "acceptMappedClaims": null,
    "accessTokenAcceptedVersion": 2,
    "addIns": [],
    "allowPublicClient": false,
    "appId": "xxxxdf64-9136-4d2b-xxxx-e02ffxxxxe36",
    "appRoles": [],
    "oauth2AllowUrlPathMatching": false,
    "createdDateTime": "2019-12-06T14:31:53Z",
    "groupMembershipClaims": null,
    "identifierUris": [
        "https://domain-1.onmicrosoft.com/api"
    ],
    "informationalUrls": {
        "termsOfService": null,
        "support": null,
        "privacy": null,
        "marketing": null
    },
    "keyCredentials": [],
    "knownClientApplications": [],
    "logoUrl": null,
    "logoutUrl": null,
    "name": "SameNameAPI",
    "oauth2AllowIdTokenImplicitFlow": true,
    "oauth2AllowImplicitFlow": true,
    "oauth2Permissions": [
        {
            "adminConsentDescription": "Read User Files",
            "adminConsentDisplayName": "Read User Files",
            "id": "38115032-56b3-xxxx-9d81-xxxx039xx73f",
            "isEnabled": true,
            "lang": null,
            "origin": "Application",
            "type": "Admin",
            "userConsentDescription": "Read User Files",
            "userConsentDisplayName": "Read User Files",
            "value": "Files.Read"
        }
    ],
    "oauth2RequirePostResponse": false,
    "optionalClaims": null,
    "orgRestrictions": [],
    "parentalControlSettings": {
        "countriesBlockedForMinors": [],
        "legalAgeGroupRule": "Allow"
    },
    "passwordCredentials": [
        {
            "customKeyIdentifier": null,
            "endDate": "2020-12-11T20:10:26.76Z",
            "keyId": "d08800f2-ef0b-490d-9905-44fa82c1eab3",
            "startDate": "2019-12-11T20:10:40.672Z",
            "value": null,
            "createdOn": "2019-12-11T20:10:23.7962051Z",
            "hint": "U9L",
            "displayName": "clientCreator"
        }
    ],
    "preAuthorizedApplications": [],
    "publisherDomain": "domain-1.onmicrosoft.com",
    "replyUrlsWithType": [],
    "requiredResourceAccess": [
        {
            "resourceAppId": "00000003-0000-0000-c000-000000000000",
            "resourceAccess": [
                {
                    "id": "37f7f235-527c-4136-accd-4a02d197296e",
                    "type": "Scope"
                },
                {
                    "id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182",
                    "type": "Scope"
                },
                {
                    "id": "dc5007c0-2d7d-4c42-879c-2dab87571379",
                    "type": "Role"
                },
                {
                    "id": "656f6061-f9fe-4807-9708-6a2e0934df76",
                    "type": "Role"
                },
                {
                    "id": "1b0c317f-dd31-4305-9932-259a8b6e8099",
                    "type": "Role"
                },
                {
                    "id": "65319a09-a2be-469d-8782-f6b07debf789",
                    "type": "Role"
                },
                {
                    "id": "405a51b5-8d8d-430b-9842-8be4b0e9f324",
                    "type": "Role"
                },
                {
                    "id": "09850681-111b-4a89-9bed-3f2cae46d706",
                    "type": "Role"
                },
                {
                    "id": "df021288-bdef-4463-88db-98f22de89214",
                    "type": "Role"
                },
                {
                    "id": "741f803b-c850-494e-b5df-cde7c675a1ca",
                    "type": "Role"
                }
            ]
        },
        {
            "resourceAppId": "00000002-0000-0000-c000-000000000000",
            "resourceAccess": [
                {
                    "id": "5778995a-e1bf-45b8-affa-663a9f3f4d04",
                    "type": "Role"
                },
                {
                    "id": "78c8a3c8-a07e-4b9e-af1b-b5ccab50a175",
                    "type": "Role"
                }
            ]
        },
        {
            "resourceAppId": "xxxxdf64-9136-4d2b-xxxx-e02ffxxxxe36",
            "resourceAccess": [
                {
                    "id": "38115032-56b3-xxxx-9d81-xxxx039xx73f",
                    "type": "Scope"
                }
            ]
        }
    ],
    "samlMetadataUrl": null,
    "signInUrl": null,
    "signInAudience": "AzureADandPersonalMicrosoftAccount",
    "tags": [],
    "tokenEncryptionKeyId": null,
    "verifiedPublisher": {
        "displayName": null,
        "verifiedPublisherId": null,
        "addedDateTime": null
    }
}

Манифест приложения Tenant 2 API

{
    "id": "ebexxxx-xxxx-41aa-80d4-512xxxxxx3ff",
    "acceptMappedClaims": null,
    "accessTokenAcceptedVersion": 2,
    "addIns": [],
    "allowPublicClient": false,
    "appId": "e633f406-xxxx-4c7a-85af-xxxxxxxxx436",
    "appRoles": [],
    "oauth2AllowUrlPathMatching": false,
    "createdDateTime": "2020-06-05T16:19:02Z",
    "groupMembershipClaims": null,
    "identifierUris": [
        "https://domain-2.onmicrosoft.com/api"
    ],
    "informationalUrls": {
        "termsOfService": null,
        "support": null,
        "privacy": null,
        "marketing": null
    },
    "keyCredentials": [],
    "knownClientApplications": [],
    "logoUrl": null,
    "logoutUrl": null,
    "name": "SameNameAPI",
    "oauth2AllowIdTokenImplicitFlow": true,
    "oauth2AllowImplicitFlow": true,
    "oauth2Permissions": [
        {
            "adminConsentDescription": "Read User Files",
            "adminConsentDisplayName": "Read User Files",
            "id": "7b95e412-c753-4611-xxxx-xxxxx7aa4d78",
            "isEnabled": true,
            "lang": null,
            "origin": "Application",
            "type": "Admin",
            "userConsentDescription": "Read User Files",
            "userConsentDisplayName": "Read User Files",
            "value": "Files.Read"
        }
    ],
    "oauth2RequirePostResponse": false,
    "optionalClaims": null,
    "orgRestrictions": [],
    "parentalControlSettings": {
        "countriesBlockedForMinors": [],
        "legalAgeGroupRule": "Allow"
    },
    "passwordCredentials": [
        {
            "customKeyIdentifier": null,
            "endDate": "2299-12-31T03:00:00Z",
            "keyId": "99df4466-e1e7-4279-9699-063efacfbed7",
            "startDate": "2020-06-05T16:45:24.082Z",
            "value": null,
            "createdOn": "2020-06-05T16:45:25.2186779Z",
            "hint": "9b_",
            "displayName": "clientCreator"
        }
    ],
    "preAuthorizedApplications": [],
    "publisherDomain": "sgmembershipb2bdev.onmicrosoft.com",
    "replyUrlsWithType": [],
    "requiredResourceAccess": [
        {
            "resourceAppId": "e633f406-xxxx-4c7a-85af-xxxxxxxxx436",
            "resourceAccess": [
                {
                    "id": "7b95e412-c753-4611-xxxx-xxxxx7aa4d78",
                    "type": "Scope"
                }
            ]
        },
        {
            "resourceAppId": "00000003-0000-0000-c000-000000000000",
            "resourceAccess": [
                {
                    "id": "37f7f235-527c-4136-accd-4a02d197296e",
                    "type": "Scope"
                },
                {
                    "id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182",
                    "type": "Scope"
                },
                {
                    "id": "dc5007c0-2d7d-4c42-879c-2dab87571379",
                    "type": "Role"
                },
                {
                    "id": "656f6061-f9fe-4807-9708-6a2e0934df76",
                    "type": "Role"
                },
                {
                    "id": "1b0c317f-dd31-4305-9932-259a8b6e8099",
                    "type": "Role"
                },
                {
                    "id": "65319a09-a2be-469d-8782-f6b07debf789",
                    "type": "Role"
                },
                {
                    "id": "405a51b5-8d8d-430b-9842-8be4b0e9f324",
                    "type": "Role"
                },
                {
                    "id": "09850681-111b-4a89-9bed-3f2cae46d706",
                    "type": "Role"
                },
                {
                    "id": "df021288-bdef-4463-88db-98f22de89214",
                    "type": "Role"
                },
                {
                    "id": "741f803b-c850-494e-b5df-cde7c675a1ca",
                    "type": "Role"
                }
            ]
        },
        {
            "resourceAppId": "00000002-0000-0000-c000-000000000000",
            "resourceAccess": [
                {
                    "id": "5778995a-e1bf-45b8-affa-663a9f3f4d04",
                    "type": "Role"
                },
                {
                    "id": "78c8a3c8-a07e-4b9e-af1b-b5ccab50a175",
                    "type": "Role"
                }
            ]
        }
    ],
    "samlMetadataUrl": null,
    "signInUrl": null,
    "signInAudience": "AzureADandPersonalMicrosoftAccount",
    "tags": [],
    "tokenEncryptionKeyId": null,
    "verifiedPublisher": {
        "displayName": null,
        "verifiedPublisherId": null,
        "addedDateTime": null
    }
}

Манифест приложения Tenant 1 Auth

{
    "id": "5a6e70fe-xxx-4687-b77c-xxxxxxxxx3cf",
    "acceptMappedClaims": null,
    "accessTokenAcceptedVersion": 2,
    "addIns": [],
    "allowPublicClient": true,
    "appId": "877fc335-xxxx-xxx-b175-xxxxxxxxxddb",
    "appRoles": [],
    "oauth2AllowUrlPathMatching": false,
    "createdDateTime": "2019-12-09T13:09:50Z",
    "groupMembershipClaims": null,
    "identifierUris": [],
    "informationalUrls": {
        "termsOfService": null,
        "support": null,
        "privacy": null,
        "marketing": null
    },
    "keyCredentials": [],
    "knownClientApplications": [],
    "logoUrl": null,
    "logoutUrl": null,
    "name": "ropc_auth2",
    "oauth2AllowIdTokenImplicitFlow": false,
    "oauth2AllowImplicitFlow": true,
    "oauth2Permissions": [],
    "oauth2RequirePostResponse": false,
    "optionalClaims": null,
    "orgRestrictions": [],
    "parentalControlSettings": {
        "countriesBlockedForMinors": [],
        "legalAgeGroupRule": "Allow"
    },
    "passwordCredentials": [],
    "preAuthorizedApplications": [],
    "publisherDomain": "domain-1.onmicrosoft.com",
    "replyUrlsWithType": [
        {
            "url": "https://login.microsoftonline.com/tfp/oauth2/nativeclient",
            "type": "InstalledClient"
        },
        {
            "url": "https://domain-1.b2clogin.com/tfp/oauth2/nativeclient",
            "type": "InstalledClient"
        },
        {
            "url": "urn:ietf:wg:oauth:2.0:oob",
            "type": "InstalledClient"
        }
    ],
    "requiredResourceAccess": [],
    "samlMetadataUrl": null,
    "signInUrl": null,
    "signInAudience": "AzureADandPersonalMicrosoftAccount",
    "tags": [],
    "tokenEncryptionKeyId": null,
    "verifiedPublisher": {
        "displayName": null,
        "verifiedPublisherId": null,
        "addedDateTime": null
    }
}

Манифест приложения Tenant 2 Auth

{
    "id": "7c3d8eeb-xxxx-xxxx-b901-xxxxxxxxxe07",
    "acceptMappedClaims": null,
    "accessTokenAcceptedVersion": 2,
    "addIns": [],
    "allowPublicClient": true,
    "appId": "26c414be-xxxx-xxxx-b55d-xxxxxxxxxc40",
    "appRoles": [],
    "oauth2AllowUrlPathMatching": false,
    "createdDateTime": "2020-06-05T15:08:34Z",
    "groupMembershipClaims": null,
    "identifierUris": [],
    "informationalUrls": {
        "termsOfService": null,
        "support": null,
        "privacy": null,
        "marketing": null
    },
    "keyCredentials": [],
    "knownClientApplications": [],
    "logoUrl": null,
    "logoutUrl": null,
    "name": "ROPC_Auth_app",
    "oauth2AllowIdTokenImplicitFlow": false,
    "oauth2AllowImplicitFlow": true,
    "oauth2Permissions": [],
    "oauth2RequirePostResponse": false,
    "optionalClaims": null,
    "orgRestrictions": [],
    "parentalControlSettings": {
        "countriesBlockedForMinors": [],
        "legalAgeGroupRule": "Allow"
    },
    "passwordCredentials": [],
    "preAuthorizedApplications": [],
    "publisherDomain": "domain-2.onmicrosoft.com",
    "replyUrlsWithType": [
        {
            "url": "urn:ietf:wg:oauth:2.0:oob",
            "type": "InstalledClient"
        },
        {
            "url": "https://domain-2.b2clogin.com/tfp/oauth2/nativeclient",
            "type": "InstalledClient"
        },
        {
            "url": "https://login.microsoftonline.com/tfp/oauth2/nativeclient",
            "type": "InstalledClient"
        }
    ],
    "requiredResourceAccess": [],
    "samlMetadataUrl": null,
    "signInUrl": null,
    "signInAudience": "AzureADandPersonalMicrosoftAccount",
    "tags": [],
    "tokenEncryptionKeyId": null,
    "verifiedPublisher": {
        "displayName": null,
        "verifiedPublisherId": null,
        "addedDateTime": null
    }
}

Использование

Конфигурация клиента GraphAPI

// Startup.cs --> ConfigureServices
services.AddScoped<IB2CGraphClient>(provider =>
    {
      var conf = provider.GetService<IConfigurationRoot>();
      var section = conf.GetSection("AzureAd");
      B2CGraphClient client = new B2CGraphClient(section.GetValue<string>("ClientId"), 
         section.GetValue<string>("ClientSecret"), section.GetValue<string>("Domain"));
      return client;
     });

Метод пользовательского PATCH

// GraphClient.cs
private async Task<string> SendGraphPatchRequest(string api, string json)
    {                
     AuthenticationResult result = await 
authContext.AcquireTokenAsync(Globals.aadGraphResourceId, credential);

     HttpClient http = new HttpClient();
     string url = Globals.aadGraphEndpoint + tenant + api + "?" + Globals.aadGraphVersion;                

     HttpRequestMessage request = new HttpRequestMessage(new HttpMethod("PATCH"), URL);
     request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

     request.Content = new StringContent(json, Encoding.UTF8, "application/json");
     HttpResponseMessage response = await http.SendAsync(request);

     if (!response.IsSuccessStatusCode)
        {
          string error = await response.Content.ReadAsStringAsync();
          object formatted = JsonConvert.DeserializeObject(error);
          throw new WebException("Error Calling the Graph API: \n" + JsonConvert.SerializeObject(formatted, Formatting.Indented));
                }



    return await response.Content.ReadAsStringAsync();
   }

Я отладил эти строки кодов, и изменение конфигурации в приложении выполняется с помощью настроек. методы с правильной информацией о клиенте.

Запрос и ответ

Запрос с использованием клиента 1

{
Method: PATCH, 
RequestUri: 'https://graph.windows.net/domain-1.onmicrosoft.com/users/35761bb2-8729-xxxx-xxxx-xxxxxxxxxfe9?api-version=1.6', 
Version: 1.1, 
Content: System.Net.Http.StringContent, 
Headers:
{
  Authorization: Bearer some_token
  Request-Context: appId=cid-v1:d6b30135-xxxx-xxxx-b5e2-xxxxxxxxxacf
  Request-Id: |fbde7acc88133b4ab15e1ca11cd1cb64.xxxxxxxxxx.
  traceparent: 00-fbde7acc88133b4ab15e1caxxxxxcb64-a99xxxxx8cfb9e4c-00
  Content-Type: application/json; charset=utf-8
  Content-Length: 172
}}

Клиент полезной нагрузки токена 1

{
    "aud": "https://graph.windows.net/",
    "iss": "https://sts.windows.net/fa11ae53-fc0b-xxx-xxxx-xxxxxxxxx48a/",
    "iat": 1592416988,
    "nbf": 1592416988,
    "exp": 1592420888,
    "aio": "42dgYDDxxxxxx4Ut954+Lpope+noSwA=",
    "appid": "d7fddf64-xxxx-4d2b-xxxx-xxxxxxxxxe36",
    "appidacr": "1",
    "idp": "https://sts.windows.net/fa11ae53-fc0b-xxxx-a575-xxxxxxxx48a/",
    "oid": "b4eb0d70-2ad1-xxxx-a5a1-xxxxxxxxdfa",
    "roles": [
      "Directory.Read.All",
      "Directory.ReadWrite.All"
    ],
    "sub": "b4eb0d70-xxxx-4c37-xxxx-xxxxxxxxdfa",
    "tenant_region_scope": "NA",
    "tid": "fa11ae53-fc0b-xxxxx-xxxx-xxxxxxxx48a",
    "uti": "xxxxxxxxxxxxxxxxbAA",
    "ver": "1.0"
  }

Ответ с использованием Теннант 1

{
StatusCode: 204, 
ReasonPhrase: 'No Content', 
Version: 1.1, 
Content: System.Net.Http.HttpConnectionResponseContent, 
Headers: {...}
}

Запрос с использованием арендатора 2

{
  Method: PATCH, 
  RequestUri: 'https://graph.windows.net/domain-2.onmicrosoft.com/users/59ef7da0-xxxx-xxxx-8b05-xxxxxxxxxd13?api-version=1.6', 
  Version: 1.1, 
  Content: System.Net.Http.StringContent, 
  Headers:
  {
    Authorization: Bearer some_token
    Request-Context: appId=cid-v1:d6b30135-b6ac-xxxx-b5e2-xxxxxxxxxacf
    Request-Id: |8d281xxxxxxxxx4acef74298ec03dd1.79867ebb617a364c.
  traceparent: 00-8d28xxxxxxxxb44acef74298ec03dd1-79867ebb617a364c-00
    Content-Type: application/json; charset=utf-8
    Content-Length: 172
  }
}

Клиент полезной нагрузки токена 2

{
    "aud": "https://graph.windows.net/",
    "iss": "https://sts.windows.net/06b0c6f1-7524-xxxx-xxxx-xxxxxxxxx731/",
    "iat": 1592418325,
    "nbf": 1592418325,
    "exp": 1592422225,
    "aio": "42dgYGxxxxxxxxxx8C3BWc6r6fbAwA=",
    "appid": "e633f406-xxxx-4c7a-xxxx-xxxxxxxxx436",
    "appidacr": "1",
    "idp": "https://sts.windows.net/06b0c6f1-7524-xxxx-88be-xxxxxxxx731/",
    "oid": "12d9a685-6083-xxxx-xxxx-xxxxxxxx4db",
    "roles": [
      "Directory.Read.All",
      "Directory.ReadWrite.All"
    ],
    "sub": "12d9a685-xxxx-47e1-xxxx-xxxxxxxxx4db",
    "tenant_region_scope": "NA",
    "tid": "06b0c6f1-7524-xxxx-xxxx-xxxxxxxxx731",
    "uti": "xxxxxxxxxxxxxxxuAA",
    "ver": "1.0"
  }

Ответный арендатор 2

{
StatusCode: 403, 
ReasonPhrase: 'Forbidden', 
Version: 1.1, 
Content: System.Net.Http.HttpConnectionResponseContent, 
Headers: 
  {
   ...   
  }
}

// Content
{
  "odata.error": {
    "code": "Authorization_RequestDenied",
    "message": {
      "lang": "en",
      "value": "Insufficient privileges to complete the operation."
    },
    "requestId": "9adf43b9-xxxx-xxxx-a393-xxxxxxxxxd54",
    "date": "2020-06-17T17:47:19"
  }
}
...