【问题标题】:Integration between MS Dynamics CRM 2013 and LAMPMS Dynamics CRM 2013 和 LAMP 之间的集成
【发布时间】:2014-12-09 02:12:26
【问题描述】:

我是一名网络开发人员,致力于为客户的网站重建提供后端服务。他们希望将现有的 CRM 系统与新站点集成,以便站点可以对系统执行 CRUD 查询。但是,我正在努力成功地正确使用 Microsoft 系统进行身份验证,并且希望获得一些帮助来规划最佳策略以使其正常工作。

系统概览:

服务器:MS Dynamics CRM 2013(面向 Internet 的部署),使用 Active Directory 进行身份验证

客户端:LAMP(将运行 Drupal 7,但这是我真正知道如何使用的部分!)

首先,我尝试了下面描述的身份验证方法,在“发现 OAuth 端点 URL”部分:

http://msdn.microsoft.com/en-gb/library/dn531009.aspx#bkmk_oauthurl

为此,我在命令行中使用了以下 curl:

curl -H "Authorization: Bearer" http://crm.example.com/XRMServices/2011/Organization.svc -v

它给出以下输出:

* Hostname was NOT found in DNS cache
*   Trying xx.xx.xx.xx...
* Connected to crm.example.com (xx.xx.xx.xx) port 80 (#0)
> GET /XRMServices/2011/Organization.svc HTTP/1.1
> User-Agent: curl/7.35.0
> Host: crm.example.com
> Accept: */*
> Authorization: Bearer
>
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Length: 3165
< Content-Type: text/html; charset=UTF-8
* Server Microsoft-IIS/8.0 is not blacklisted
< Server: Microsoft-IIS/8.0
< X-AspNet-Version: 4.0.30319
< Set-Cookie: ReqClientId=ee9c75fe-db2e-4775-a71e-c2708c46748b; expires=Tue, 14-Oct-2064 09:16:06 GMT; path=/; HttpOnly
< X-Powered-By: ASP.NET
< Date: Tue, 14 Oct 2014 09:16:06 GMT
<
<HTML>...

但没有提到授权 uri :(

我还尝试了相同的命令,其 url 以“discovery.svc”、“organization.svc/web”、“discovery.svc/web”结尾。后两者确实在响应中包含了“WWW-Authenticate”字段,如下所示:

< WWW-Authenticate: Negotiate
< WWW-Authenticate: NTLM

这让我相信我尝试了错误的方法,应该调查 MS 的 NTLM 身份验证。

我确定 PHP-cURL 可以使用 NTLM,所以我的第二种方法涉及从代码发送 SOAP 请求。与此 StackOverflow 线程中的代码类似:

php - access dynamics crm 2011 with web services

这是我的代码:

//sample SOAP envelope from StackOverflow thead
$SOAPEnv = <<<ENV
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
 <s:Body>
  <Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services"
           xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   <request i:type="b:AssignRequest"
            xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts"
            xmlns:b="http://schemas.microsoft.com/crm/2011/Contracts">
    <a:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
     <a:KeyValuePairOfstringanyType>
      <c:key>Target</c:key>
      <c:value i:type="a:EntityReference">
       <a:Id>XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</a:Id>
       <a:LogicalName>account</a:LogicalName>
       <a:Name i:nil="true" />
      </c:value>
     </a:KeyValuePairOfstringanyType>
     <a:KeyValuePairOfstringanyType>
      <c:key>Assignee</c:key>
      <c:value i:type="a:EntityReference">
       <a:Id>XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</a:Id>
       <a:LogicalName>systemuser</a:LogicalName>
       <a:Name i:nil="true" />
      </c:value>
     </a:KeyValuePairOfstringanyType>
    </a:Parameters>
    <a:RequestId i:nil="true" />
    <a:RequestName>Assign</a:RequestName>
   </request>
  </Execute>
 </s:Body>
</s:Envelope>
ENV;

$headers = array(
  'Method: POST',
  'Connection: Keep-Alive',
  'User-Agent: PHP-SOAP-CURL',
  'Content-Type: text/xml; charset=utf-8',
  "SOAPAction: http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute",  
);


$url = 'http://crm.example.com/XRMServices/2011/Organization.svc/web';
$username  = 'myusername';
$password  = 'MyP@55w0rd';

$ch = curl_init();

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $SOAPEnv);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);

$output = curl_exec($ch);

这给出了 SOAP 响应:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <s:Fault>
      <faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:FailedAuthentication</faultcode>
      <faultstring xml:lang="en-GB">Access is denied.</faultstring>
    </s:Fault>
  </s:Body>
</s:Envelope>

令人鼓舞的是,这是一个 SOAP 响应,所以我觉得我很接近了。它肯定是使用我提供的凭据进行身份验证,因为如果我更改它们,我不会得到任何 SOAP。但我觉得必须有另一个级别的身份验证才能让 SOAP 端点知道我是合法客户端。

所以我有点卡住了,因为关于将 SOAP 与 Dynamics 结合使用的文档似乎是从 Microsoft 的 SDK 的角度编写的,而且对于我经验中只真正了解 PHP 的人来说肯定没有帮助。

如果有人可以对我的方法提供任何反馈,我将不胜感激。如果你能指出我下一步的正确方向,那就更好了。而且我在这个项目上的时间不多了,所以已经把这个告诉了专家。请注意,我是一个相对较新的开发人员,所以如果你不得不稍微降低你的答案,请提前道歉:)

非常感谢, 阿什瓦

【问题讨论】:

  • 你觉得这个怎么样?你有进步吗??我花了相当多的时间将 Drupal 连接到 CRM Online。我已经让它工作了,但是我从来没有破解过 Active Directory 难题。我的调查在我的博客上。 crmtroubleshoot.blogspot.com.au/search/label/soap Active Directory - SOAP - CRM 似乎是 stackoverflow 上反复出现的问题,我很想知道您是否想通了
  • 最终没有自己进行身份验证。不得不聘请一位 MS 开发人员来构建一些中间件来与 Dynamics API 对话。很遗憾,跨平台制作这样的作品是如此困难。虽然这可能是最好的,但这意味着我们可以利用一些更自定义的 CRM 功能。

标签: authentication curl soap crm microsoft-dynamics


【解决方案1】:

我在一些相关的事情上苦苦挣扎。我可以获得示例 Python 代码来连接具有租户名称的云托管版本的 CRM,但我试图与具有自己的 STS(安全令牌服务器)的本地/IFD 安装集成。使用该域对我不起作用。我不知道redirect_uri 是什么。

一旦我意识到我必须连接到 CRM api 端点才能获得Bearer authorization_uri,它就对我有效。

如果您在 foo.crm.dynamics.com 有一个 Dynamics CRM 实例,您可以 curl 这个

curl -I https://foo.crm.dynamics.com/api/data/v8.0/WhoAmI

将 foo 替换为您的 CRM 实例的名称,然后返回类似的内容

HTTP/1.1 401 未经授权 缓存控制:私有 内容长度:49 内容类型:文本/html 服务器:Microsoft-IIS/8.X REQ_ID:995XXXX-XXXX-XXXX-XXX-XXXXXXXe7 设置 Cookie:ReqClientId=95XXXX-XXXX-XXXX-XXX-XXXXXXXe7; expires=周三,XX-Jan-XX 15:MM:SS GMT;路径=/;安全的; HttpOnly WWW-Authenticate: Bearer authorization_uri=https://login.windows.net/62d6e7de-bbbb-cccc-dddd-4f9605b2ad79/oauth2/authorize, resource_id=https://foo.crm.dynamics.com/ X-Powered-By: ASP.NET ...

UUID 62d6e7de-bbbb-cccc-dddd-4f9605b2ad79 是您正在寻找的。由于一些解释不充分的原因,我需要将域从 login.windows.net 切换到 login.microsoftonline.com。

https://login.microsoftonline.com/62d6e7de-bbbb-cccc-dddd-4f9605b2ad79。

然后我可以使用这个带有用户名和密码的示例代码并实际连接。

https://github.com/jlattimer/CrmWebApiPython/blob/master/CrmConnect

【讨论】:

    猜你喜欢
    • 2014-03-07
    • 2011-09-05
    • 2016-02-12
    • 2015-10-05
    • 2012-12-07
    • 1970-01-01
    • 2019-02-25
    • 2011-10-12
    • 1970-01-01
    相关资源
    最近更新 更多