【问题标题】:Unauthorized Error: Query or Save Contact/lead in Dynamics CRM Using C#未经授权的错误:使用 C# 在 Dynamics CRM 中查询或保存联系人/潜在客户
【发布时间】:2019-03-07 13:50:29
【问题描述】:

我正在使用以下 Web api 从 Dynamics CRM 中查询数据

ServicePointManager.Expect100Continue = true;
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                    HttpClient client = new HttpClient(new HttpClientHandler() { Credentials = new NetworkCredential("xxxxx@mydomain.com", "!@Demo1$#2") });
                    client.BaseAddress = new Uri("https://xxxxx.crm.dynamics.com");
                    client.Timeout = new TimeSpan(0, 2, 0);
                    string contactAltUri = client.BaseAddress + "api/data/v9.0/accounts?$select=name&$top=3";
                    HttpResponseMessage createResponseAlt1 = await client.GetAsync(contactAltUri);

现在在对象createResponseAlt1 中,我可以看到以下未经授权的错误。查询数据并将数据保存到 Dynamics CRM 的正确方法是什么?我有用户名、密码和 Ms crm 子域 url。

{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  x-ms-service-request-id: 4b323404-cc13-407c-bb6d-56b61823ab84
  REQ_ID: 4b323404-cc13-407c-bb6d-56b61823ab84
  AuthActivityId: 85696c96-6803-4664-9391-d28f45d1766a
  NativeWebSession-Version: 2
  Date: Thu, 07 Mar 2019 13:42:36 GMT
  Set-Cookie: ApplicationGatewayAffinity=03da1c2a15fe28b54ffa99b7eab01d12cd9b55dfb1779b6cccce0809ec64f39a;Path=/;Domain=xxxxx.crm.dynamics.com
  Server: 
  WWW-Authenticate: Bearer authorization_uri=https://login.microsoftonline.com/e20b0aa3-6ec3-4272-a76a-aaa32e0f10d6/oauth2/authorize, resource_id=https://xxxxx.crm.dynamics.com/
  Content-Length: 0
}}

【问题讨论】:

  • 所使用的登录帐户应具有在 CRM 中分配的安全角色。可以在浏览器中登录吗?
  • 是的,我可以在浏览器中登录
  • 复制你在contactAltUti变量中得到的值并粘贴到浏览器地址栏中,看看它是否有效?
  • 您如何将 Rest Builder github.com/jlattimer/CRMRESTBuilder 添加到您的 CRM 组织中,然后尝试您的 Webapi 查询。我不确定使用 Webapi 是否是您查询/更新 CRM 的唯一必需方法。如果不能,我可以建议另一种方式,使用组织服务。这是参考arunpotti.wordpress.com/2018/02/03/… 的示例链接

标签: c# dynamics-crm dynamics-crm-online dynamics-365


【解决方案1】:

第 1 步:在 Azure Active Directory (AAD) 中注册应用程序以获取应用程序 ID(也称为客户端 ID)。 Read more

第 2 步:使用客户端 ID 使用 OAuth 获取身份验证令牌,因为 CRM 在线需要使用 AAD 进行身份验证,这是我们必须遵循的方法。 Read more

代码示例

        static string serviceUri = "https://yourorg.crmx.dynamics.com/";
        static string redirectUrl = "https://yourorg.api.crmx.dynamics.com/api/data/v9.0/";

        public static string GetAuthToken()
        {

            // TODO Substitute your app registration values that can be obtained after you
            // register the app in Active Directory on the Microsoft Azure portal.
            string clientId = "3oi467rf-2336-4039-b82i-7c5b859c7be0"; // Client ID after app registration
            string userName = "xyz@youOrg.onmicrosoft.com";
            string password = "Password";
            UserCredential cred = new UserCredential(userName, password);

            // Authenticate the registered application with Azure Active Directory.
            AuthenticationContext authContext = new AuthenticationContext("https://login.windows.net/common", false);
            AuthenticationResult result = authContext.AcquireToken(serviceUri, clientId, cred);
            return result.AccessToken;
        }
        public static void RetrieveAccounts(string authToken)
        {
            HttpClient httpClient = null;
            httpClient = new HttpClient();
            //Default Request Headers needed to be added in the HttpClient Object
            httpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
            httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            //Set the Authorization header with the Access Token received specifying the Credentials
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);

            httpClient.BaseAddress = new Uri(redirectUrl);
            var response = httpClient.GetAsync("accounts?$select=name").Result;
            if (response.IsSuccessStatusCode)
            {
                var accounts = response.Content.ReadAsStringAsync().Result;
            }
        }

Reference

【讨论】:

  • 我也在做同样的事情,但我的回复仍然是 401 Unauthorized。您是否在实例级别或 AAD 应用程序级别进行了任何设置/权限来完成这项工作?我正在关注这篇文章 - docs.microsoft.com/en-us/powerapps/developer/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多