Search code examples
node.jslyncucwa

UCWA Lync authentication - 500 web ticket is invalid


I'm trying to create a simple client for Lync using Nodejs. Base on http://ucwa.lync.com/documentation/KeyTasks-CreateApplication I've made someting like this. It works until last step #9 when I should register my app with UCWA. Server responds with code 500 and silly explanation

There is a problem with the resource you are looking for, and it cannot be displayed

And headers

x-ms-diagnostics': '28032;source="mysource";reason="The web ticket is invalid."'

var http = require('request-promise');
var lync = {};

lync.setup = function(email, password){
    var self = this;
    var hostname = email.split('@');
    this.username = email;

    //discover urls
    return http.get('http://lyncdiscover.'+hostname[1])
        .then(function(d) {
            var parsed = JSON.parse(d);
            self.urls = {
                self: parsed._links.self.href,
                user: parsed._links.user.href,
                xframe: parsed._links.xframe.href
            };
            return http.get(self.urls.user);
        }).catch(function(err){
            if(err.statusCode == 401){
                var toParse = err.response.headers['www-authenticate'];
                var Oauth = toParse.match(/https:\/\/[\d\w\./_-]*/i)[0];

                var loginPost = {
                    grant_type: 'password',
                    username: email,
                    password: password
                };

                return http.post(Oauth, {form:loginPost});
            }
            return false
        }).then(function(data){
            var parsed = JSON.parse(data);
            //setup authorization
            http = http.defaults({
                headers: {Authorization: parsed.token_type + ' ' + parsed.access_token}
            });
            //console.log(self.urls.user);
            //console.log('Authorization:'+ parsed.token_type + ' ' + parsed.access_token);
            return http.get(self.urls.user);

        }).then(function(data){
            var parsed = JSON.parse(data);
            self.urls.applications = parsed._links.applications.href;

            var registerApp = {
                culture : "en-us",
                endpointId : "2d9dc28d-4673-4035-825c-feb64be28e4e",
                userAgent : "Test"
            };
            var r = "{'userAgent': 'NodeJs',  'endpointId' : '2d9dc28d-4673-4035-825c-feb64be28e4e', 'culture': 'en-US'}";
            return http.post(self.urls.applications, {body: registerApp, json:true});
        })
        .then(function(data){
            console.log(data);
        })
        .catch(function(err){

            console.log(err);
            return false;
        });
};



//run app
lync.setup('login@domain.com', 'password').then(function(ret){

});

One key point here. It's not my server. I just have an account over there and I can login with official Lync client or Pidgin plugin. Are there some extra steps to "allow" my app to work with UCWA?

@ShelbyZ I can easily authorize using Oauth. I'm receiving authorization token so I'm logged in.

I'm receiving json similar to

"_links":{ "self":{"href":"link"}, "applications":{"href":"i need this"}, "xframe":{"href":"link"} } }

Now. I need to "register my application" doing POST. In this last step I get 500 code response. I hope It's not related with that @Matthew Proctor said.. becouse I cannot simple administrate the server


Solution

  • Thank you @ShelbyZ You were right, it was split-domain scenario. Now authorization works, and I can register my app. Also example for future generations

    var http = require('request-promise');
    
    
    var lync = {};
    
    lync._authorize = function(){
    
        var self = this;
    
        var orgDomain = self.urls.user.match(/https:\/\/([\w\d\.]+)/i)[0];
        //console.log(orgDomain);
    
        http.get(self.urls.user).catch(function(err){
            if(err.statusCode == 401){
                var toParse = err.response.headers['www-authenticate'];
                var Oauth = toParse.match(/https:\/\/[\d\w\./_-]+/i)[0];
    
                var loginPost = {
                    grant_type: 'password',
                    username: self.username,
                    password: self.password
                };
    
                return http.post(Oauth, {form:loginPost});
            }
        }).then(function(data){
            if(data) {
                var parsed = JSON.parse(data);
                //setup authorization
                http = http.defaults({
                    headers: {Authorization: parsed.token_type + ' ' + parsed.access_token}
                });
                return http.get(self.urls.user);
            }
        }).then(function(data){
            //check for split-domain scenario
            var parsed = JSON.parse(data);
            var domain = parsed._links.self.href.match(/https:\/\/([\w\d\.]+)/i)[0];
            console.log('[1] '+orgDomain);
            console.log('[2] '+domain);
    
            if(domain!== orgDomain){
                //split domain scenario
                self.urls.user = self.urls.user.replace(orgDomain, domain);
                http = http.defaults({
                    headers: {Authorization: null}
                });
    
                self._authorize();
            } else { //create app
                var parsed = JSON.parse(data);
                self.urls.applications = parsed._links.applications.href;
    
                var registerApp = {
                    culture : "en-us",
                    endpointId : "2d9dc28d-4673-4035-825c-feb64be28e4e",
                    userAgent : "NodeJs client"
                };
                return http.post(self.urls.applications, {body: registerApp, json:true});
            }
        }).then(function(app){
            console.log(app);
        });
    
    };
    
    lync.setup = function(email, password){
        var self = this;
        var hostname = email.split('@');
        this.username = email;
        this.password = password;
    
        //discover urls
        return http.get('http://lyncdiscover.'+hostname[1])
            .then(function(d) {
                var parsed = JSON.parse(d);
                self.urls = {
                    self: parsed._links.self.href,
                    user: parsed._links.user.href,
                    xframe: parsed._links.xframe.href
                };
                return self._authorize();
            });
    
    };
    
    
    
    //run app
    lync.setup('username@domain.com', 'password');