Использование этой конфигурации в https://github.com/Azure-Samples/ms-identity-python-webapp сработало для меня. Область действия должна включать URL-адрес API организации / среды CDS.
CLIENT_SECRET = "**********************************"
AUTHORITY = "https://login.microsoftonline.com/common"
CLIENT_ID = "3641e71b-ad98-4489-8423-f77532d0a5d5"
REDIRECT_PATH = "/getAToken"
ENDPOINT = 'https://graph.microsoft.com/v1.0/users'
CDS_ENDPOINT = "https://REPLACE_WITH_ORG_NAME.api.crm.dynamics.com/api/data/v9.0/msmrw_guides?$select=msmrw_name&$expand=msmrw_guide_Annotations"
# cds environment / crm org, MUST be a part of the scope
SCOPE = ["https://REPLACE_WITH_ORG_NAME.api.crm.dynamics.com/user_impersonation"]
SESSION_TYPE = "filesystem"
Проблема ADAL Проблема с токеном носителя Pyhton
Я неинтерактивно аутентифицируюсь с идентификатор клиента и секрет для моего REST-приложения, которое взаимодействует со службой общих данных. Сначала тестирование в Postman. Я могу успешно выполнять операции чтения и записи, используя свои учетные данные.
При реализации REST API в Python я могу выполнять операции чтения только через Azure AD Authentication Библиотека (ADAL) с версией adal==1.2.2
. Я использую те же учетные данные из моей среды Postman в Python через файл конфигурации, пример ниже. Я также протестировал этот токен, сгенерированный Python ADAL в Postman, чтобы убедиться, что я могу делать запросы get, поскольку заметил, что строки токенов отличаются от той, которую я генерирую в Python, и строки, которую я генерирую в Postman. При отправке запроса я получаю сообщение об ошибке, показанное ниже. Я думаю, мне нужно logi c в python, чтобы как-то сообщить ADAL, что пользователю, запрашивающему токен, разрешены права на запись.
Ошибка кода и почтальона
import adal
from .config import *
class AzureAuth:
bearerToken = ""
def __init__(self):
authCtx = adal.AuthenticationContext(AUTHORITY_URL)
tokenResponse = authCtx.acquire_token_with_client_credentials(RESOURCE, CLIENT_ID, CLIENT_SECRET)
self.bearerToken = tokenResponse["accessToken"]
Вот пример того, как выглядит мой config.py
.
AUTHORITY_URL=""
CDS_API_URL=""
CLIENT_ID=""
CLIENT_SECRET=""
REDIRECT_URI=""
RESOURCE="" # like "https://your_cds_environment.api.crm.dynamics.com/"
TENANT="" # like "https://login.microsoftonline.com/put_your_tenant"
Ошибка, возникающая в Почтальоне, когда я копирую, вставляет маркер Python в почтовый запрос Почтальона.
{
"error": {
"code": "0x80048306",
"message": "{\"CallerPrincipal\":{\"PrincipalId\":\"96b856f4-134c-e911-a823-000d3a1d5de8\",\"Type\":8,\"IsUserPrincipal\":true,\"IsTeamPrincipal\":false,\"TypeName\":\"user\"},\"OwnerPrincipal\":{\"PrincipalId\":\"96b856f4-134c-e911-a823-000d3a1d5de8\",\"Type\":8,\"IsUserPrincipal\":true,\"IsTeamPrincipal\":false,\"TypeName\":\"user\"},\"CallerInfo\":{\"IsSystemUser\":false,\"IsSupportUser\":false,\"IsAdministrator\":false,\"IsCustomizer\":false,\"IsDisabled\":false,\"IsIntegrationUser\":false,\"Privileges\":null,\"Teams\":null,\"Roles\":null},\"ObjectId\":\"00000000-0000-0000-0000-000000000000\",\"ObjectTypeCode\":10410,\"ObjectBusinessUnitId\":\"1abfdddc-8140-e911-a823-000d3a1a25b8\",\"OrganizationId\":\"08907b95-ee84-4861-b141-b584fecc774d\",\"EntityName\":\"msmrw_guide\",\"EntityOwnershipTypeMask\":1,\"EntityPrivileges\":[{\"Id\":\"915a1feb-2a56-4a8c-bea0-3256728785e5\",\"ObjectTypeCode\":10410,\"Name\":\"prvCreatemsmrw_guide\",\"AccessRight\":32,\"PrivilegeType\":0,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"6415b9e2-24c4-408a-a830-85c21ab8ac72\",\"ObjectTypeCode\":10410,\"Name\":\"prvReadmsmrw_guide\",\"AccessRight\":1,\"PrivilegeType\":1,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"229dfe7f-1394-47fe-84d4-8d5d7747cbd2\",\"ObjectTypeCode\":10410,\"Name\":\"prvWritemsmrw_guide\",\"AccessRight\":2,\"PrivilegeType\":2,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"d6624737-6846-49c7-bfef-25f6f482e297\",\"ObjectTypeCode\":10410,\"Name\":\"prvDeletemsmrw_guide\",\"AccessRight\":65536,\"PrivilegeType\":3,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"4f4fa37d-b977-4acf-a05a-d003ac32fc44\",\"ObjectTypeCode\":10410,\"Name\":\"prvAssignmsmrw_guide\",\"AccessRight\":524288,\"PrivilegeType\":4,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"09e5b82f-5cd8-46ea-a7ae-acbc472ae2b2\",\"ObjectTypeCode\":10410,\"Name\":\"prvSharemsmrw_guide\",\"AccessRight\":262144,\"PrivilegeType\":5,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"93b7f403-fc9b-442b-b602-9ba347ddda26\",\"ObjectTypeCode\":10410,\"Name\":\"prvAppendmsmrw_guide\",\"AccessRight\":4,\"PrivilegeType\":6,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"776967fe-67f4-4b3d-908a-dfb4306d2372\",\"ObjectTypeCode\":10410,\"Name\":\"prvAppendTomsmrw_guide\",\"AccessRight\":16,\"PrivilegeType\":7,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true}],\"RightsToCheck\":\"CreateAccess\",\"RoleAccessRights\":\"None\",\"PoaAccessRights\":\"None\",\"HsmAccessRights\":\"None\",\"Messages\":[\"PrincipalHasOwnerPrincipalWithAtLeastBasicPrivilegeDepth = False\",\"EntityUserGroupRights = None\",\"MinimumPrivilegeDepthRequired = Local\",\"GrantedRights = None\",\"SecLib::AccessCheckEx2 failed. Owner Data: roleCount=1, privilegeCount=0, accessMode=4; Principal Data: roleCount=1, privilegeCount=0, accessMode=4\"],\"IsHsmEnabled\":false,\"IsOwnerDirectReport\":false,\"IsDirectReportInOwningTeam\":false,\"IsReadAccessFromIndirectReport\":false}",
"innererror": {
"message": "{\"CallerPrincipal\":{\"PrincipalId\":\"96b856f4-134c-e911-a823-000d3a1d5de8\",\"Type\":8,\"IsUserPrincipal\":true,\"IsTeamPrincipal\":false,\"TypeName\":\"user\"},\"OwnerPrincipal\":{\"PrincipalId\":\"96b856f4-134c-e911-a823-000d3a1d5de8\",\"Type\":8,\"IsUserPrincipal\":true,\"IsTeamPrincipal\":false,\"TypeName\":\"user\"},\"CallerInfo\":{\"IsSystemUser\":false,\"IsSupportUser\":false,\"IsAdministrator\":false,\"IsCustomizer\":false,\"IsDisabled\":false,\"IsIntegrationUser\":false,\"Privileges\":null,\"Teams\":null,\"Roles\":null},\"ObjectId\":\"00000000-0000-0000-0000-000000000000\",\"ObjectTypeCode\":10410,\"ObjectBusinessUnitId\":\"1abfdddc-8140-e911-a823-000d3a1a25b8\",\"OrganizationId\":\"08907b95-ee84-4861-b141-b584fecc774d\",\"EntityName\":\"msmrw_guide\",\"EntityOwnershipTypeMask\":1,\"EntityPrivileges\":[{\"Id\":\"915a1feb-2a56-4a8c-bea0-3256728785e5\",\"ObjectTypeCode\":10410,\"Name\":\"prvCreatemsmrw_guide\",\"AccessRight\":32,\"PrivilegeType\":0,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"6415b9e2-24c4-408a-a830-85c21ab8ac72\",\"ObjectTypeCode\":10410,\"Name\":\"prvReadmsmrw_guide\",\"AccessRight\":1,\"PrivilegeType\":1,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"229dfe7f-1394-47fe-84d4-8d5d7747cbd2\",\"ObjectTypeCode\":10410,\"Name\":\"prvWritemsmrw_guide\",\"AccessRight\":2,\"PrivilegeType\":2,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"d6624737-6846-49c7-bfef-25f6f482e297\",\"ObjectTypeCode\":10410,\"Name\":\"prvDeletemsmrw_guide\",\"AccessRight\":65536,\"PrivilegeType\":3,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"4f4fa37d-b977-4acf-a05a-d003ac32fc44\",\"ObjectTypeCode\":10410,\"Name\":\"prvAssignmsmrw_guide\",\"AccessRight\":524288,\"PrivilegeType\":4,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"09e5b82f-5cd8-46ea-a7ae-acbc472ae2b2\",\"ObjectTypeCode\":10410,\"Name\":\"prvSharemsmrw_guide\",\"AccessRight\":262144,\"PrivilegeType\":5,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"93b7f403-fc9b-442b-b602-9ba347ddda26\",\"ObjectTypeCode\":10410,\"Name\":\"prvAppendmsmrw_guide\",\"AccessRight\":4,\"PrivilegeType\":6,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true},{\"Id\":\"776967fe-67f4-4b3d-908a-dfb4306d2372\",\"ObjectTypeCode\":10410,\"Name\":\"prvAppendTomsmrw_guide\",\"AccessRight\":16,\"PrivilegeType\":7,\"CanBeBasic\":true,\"CanBeLocal\":true,\"CanBeDeep\":true,\"CanBeGlobal\":true,\"CanBeEntityReference\":true,\"CanBeParentEntityReference\":true}],\"RightsToCheck\":\"CreateAccess\",\"RoleAccessRights\":\"None\",\"PoaAccessRights\":\"None\",\"HsmAccessRights\":\"None\",\"Messages\":[\"PrincipalHasOwnerPrincipalWithAtLeastBasicPrivilegeDepth = False\",\"EntityUserGroupRights = None\",\"MinimumPrivilegeDepthRequired = Local\",\"GrantedRights = None\",\"SecLib::AccessCheckEx2 failed. Owner Data: roleCount=1, privilegeCount=0, accessMode=4; Principal Data: roleCount=1, privilegeCount=0, accessMode=4\"],\"IsHsmEnabled\":false,\"IsOwnerDirectReport\":false,\"IsDirectReportInOwningTeam\":false,\"IsReadAccessFromIndirectReport\":false}",
"type": "System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]",
"stacktrace": " at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.CreateInternal(Entity entity, InvocationContext invocationContext, CallerOriginToken callerOriginToken, WebServiceType serviceType, Boolean checkAdminMode, Dictionary`2 optionalParameters)\r\n at Microsoft.Crm.Extensibility.OData.CrmODataExecutionContext.CreateOrganizationResponse(Entity entity)\r\n at Microsoft.Crm.Extensibility.OData.CrmODataServiceDataProvider.CreateEdmEntity(CrmODataExecutionContext context, String edmEntityName, EdmEntityObject entityObject, Boolean isUpsert)\r\n at Microsoft.Crm.Extensibility.OData.EntityController.PostEntitySetImplementation(String& entitySetName, EdmEntityObject entityObject)\r\n at Microsoft.PowerApps.CoreFramework.ActivityLoggerExtensions.Execute[TResult](ILogger logger, EventId eventId, ActivityType activityType, Func`1 func, IEnumerable`1 additionalCustomProperties)\r\n at Microsoft.Xrm.Telemetry.XrmTelemetryExtensions.Execute[TResult](ILogger logger, XrmTelemetryActivityType activityType, Func`1 func)\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}
}
}
Это поля, которые я заполняю в Postman при запросе токена, и значения для этих полей, я удалил секрет для безопасности.
Это разрешения, которые использует мое приложение.