Lync UCWA - 创建应用程序提供HTTP 409:冲突错误

时间:2014-10-03 06:20:52

标签: javascript api rest lync ucwa

在过去的几天里,我一直在尝试使用Microsoft的UCWA API(REST API)为我们的Lync服务开发应用程序。要使应用程序正常工作:我首先必须使用对某个URL的POST请求将其提交给API。首先,我必须通过服务器进行身份验证,并通过向API发布用户名和密码凭据来实现。然后我获得一个访问令牌,我可以通过在每个请求的标题内发布令牌来进一步请求API。我已经能够获得访问令牌,但当我尝试通过向https://lyncextws.company.com/ucwa/oauth/v1/applications发送HTTP请求来注册应用程序时:事情将开始出错。

所有这一切都是通过一个使用iframe的JavaScript文件来绕过同源策略完成的。

这就是我的代码目前的样子:

<!DOCTYPE html>
<html lang="no">
    <head>
        <meta charset="UTF-8" />
        <title>PresInfoDisp</title>
    </head>
    <body>
        <iframe src="https://lyncextws.company.com/Autodiscover/XFrame/XFrame.html" id="xFrame" style="display: none;"></iframe>
        <script type="text/javascript" src="jquery.js"></script>
        <script type="text/javascript">

        var access_token;

        var stage = 0;

        // CONNECT AND AUTHENTICATE WITH LYNC UCWA SERVICE
        function connectAndAuthenticate() {

            stage = 1;

            var request = { 
              accepts: 'application/json', 
              type: 'POST', 
              url: 'https://lyncextws.company.com/WebTicket/oauthtoken',
              data: 'grant_type=password&username=alexander@domain.company.com&password=somePassword'
            }; 
            document.getElementById('xFrame').contentWindow.postMessage(JSON.stringify(request), 'https://lyncextws.company.com/WebTicket/oauthtoken');
        }

        // REQUEST A USER RESOURCE
        function getUserResourceAuthRequest() {

            stage = 0;

            var request = { 
              accepts: 'application/json', 
              type: 'GET', 
              url: 'https://lyncextws.company.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=company.com'
            }; 
            document.getElementById('xFrame').contentWindow.postMessage(JSON.stringify(request), 'https://lyncextws.company.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=company.com');

        }

        function getUserResource() {

            stage = 2;

            var request = { 
              accepts: 'application/json', 
              type: 'GET', 
              url: 'https://lyncextws.company.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=company.com',
              headers: {Authorization: "Bearer "+access_token}
            }; 
            document.getElementById('xFrame').contentWindow.postMessage(JSON.stringify(request), 'https://lyncextws.company.com/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=company.com');

        }

        // REGISTER APPLICATION RESOURCE
        function registerApplication() {

            stage = 3;

            var request = { 
              accepts: 'application/json', 
              type: 'POST', 
              url: 'https://lyncextws.company.com/ucwa/oauth/v1/applications',
              headers: {Authorization: "Bearer "+access_token},
              data: {'userAgent': 'InfoDisp1',  'endpointId' : '2d9dc28d-4673-4035-825c-feb64be28e4e', 'culture': 'en-US'}
            }; 
            document.getElementById('xFrame').contentWindow.postMessage(JSON.stringify(request), 'https://lyncextws.company.com/ucwa/oauth/v1/applications');

        }

        // GRAB A LIST OF CONTACTS
        function listContacts() {

            stage = 4;

            var request = { 
              accepts: 'application/json', 
              type: 'GET', 
              url: 'https://lyncextws.company.com/ucwa/oauth/v1/applications',
              headers: {Authorization: "Bearer "+access_token}
            }; 
            document.getElementById('xFrame').contentWindow.postMessage(JSON.stringify(request), 'https://lyncextws.company.com/ucwa/v1/applications');

        }

        this.receiveMessage = function(message) { 

            switch(stage) {
                case 1:

                    var beforeReplace = message.data.replace("/\\/g", "");
                    var json = jQuery.parseJSON(beforeReplace);
                    var json2 = jQuery.parseJSON(json.responseText);
                    access_token = json2.access_token;
                    console.log(json2.access_token);
                    console.log(message);

                    getUserResource();

                    break;
                case 0:
                    console.log(message);

                    connectAndAuthenticate();

                    break;

                case 2:

                    var beforeReplace = message.data.replace("/\\/g", "");
                    var json = jQuery.parseJSON(beforeReplace);
                    var json2 = jQuery.parseJSON(json.responseText);
                    console.log(json2._links.applications.href);

                    window.setTimeout(function(){registerApplication()}, 5000);

                    break;
                case 3:

                    console.log(message);

                    break;
                case 4:



                break;
            }


        }; 
        window.addEventListener('message', this.receiveMessage, false);


        $(window).load(function() {
            getUserResourceAuthRequest();
            //console.log(access_token);
        });

        </script>
    </body>
</html>

当我运行此代码时:最后一个ajax查询返回错误409:Conflict,它应该返回201:Created

这是我的浏览器(谷歌浏览器)输出的内容: What my browser outputs in the developer console in Google Chrome

401:未经授权的错误应该发生,但409冲突不应该发生。所以这是我的问题: 任何人都可以发现为什么我会收到409错误,而不是我应该得到的201错误?

Microsoft的示例代码似乎工作正常,但我想避免使用它,因为我需要很长时间才能熟悉它。

如果缺少数据,您需要发现问题:请在评论中告诉我,我会提供!

4 个答案:

答案 0 :(得分:3)

如果您更换

data: {'userAgent': 'InfoDisp1',  'endpointId' : '2d9dc28d-4673-4035-825c-feb64be28e4e', 'culture': 'en-US'} 

用一串数据代替I.E.

data: "{'userAgent': 'InfoDisp1',  'endpointId' : '2d9dc28d-4673-4035-825c-feb64be28e4e', 'culture': 'en-US'}" 

似乎数据需要一个字符串,在您的示例中,您将传递一个JSON对象。这样做可以让你的例子适合我。

答案 1 :(得分:0)

问题似乎与您的静态endpointId有关。

在他们的原始帮助程序库中,他们有一个名为generateUUID()的方法,该方法位于GeneralHelper中。最好的想法是使用这种方法,但是,如果您想创建自己的方法,那就去做吧。重点是每个应用程序必须具有不同的endpointId。

答案 2 :(得分:0)

您是仅仅为了简洁而忽略了自动发现过程,还是您真的在代码中跳过自动发现并假设URI在哪里发布“创建应用程序”?

这似乎是我的第二个案例,这是不对的: 需要从用户资源请求的响应中检索创建应用程序的URI(在您发布的代码中的 getUserResource 中)。 你有一个名为 applications 的链接;它的值包含创建应用程序的正确URI。

http://ucwa.lync.com/documentation/KeyTasks-CreateApplication

P.S。我在这里发布了关于endpointId的信息,看到我无法在上面发表评论 允许在不同的客户端上使用相同的应用程序的endpointId 。绝对不能假设使用相同endpointId的不同客户端上的应用程序将产生相同的基本应用程序资源URI

答案 3 :(得分:0)

我使用curl来试验这个API时遇到了同样的问题,并且在这一点上失败了,直到我发现在那种情况下我需要将内容类型头设置为json:

curl -v --data "{'userAgent': 'test', 'endpointId': '54321', 'culture':'en-US', 'instanceID':'testinstance'}" --header 'Content-Type: application/json' --header 'Authorization: Bearer cwt=AAEBHAEFAAAAAAA..' 'https://lyncserver.com/ucwa/oauth/v1/applications'

这就是诀窍!