Partager via


UCWA sign-in fails while seeing HTTP OPTIONS request

This is a common issue that I see that is impacted by the Lync deployment itself. You have deployed the UCWA sample, and are trying to sign in, but it always fails. If you check the HTTP traces you can see the following logged towards the end:

OPTIONS https://director.nny.local/WebTicket/oauthtoken HTTP/1.1
Accept: */*
Origin: https://webdir.nnylync.info
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type, accept, x-ms-origin

HTTP/1.1 400 Bad Request
X-Ms-diagnostics: 28020;source="Director.NNY.local";reason="No valid security token."
X-MS-Server-Fqdn: Director.NNY.local

Well this is odd, an OPTIONS request?  Understanding what is going wrong here requires a little understanding of the same-origin security policy enforced by most modern browsers.  As a protection mechanism, browsers will not allow a website loaded from one domain name to make XMLHttpRequest requests to a different domain.   This creates a little conundrum for our UCWA API, since one of the goals is to allow people to embed Lync features into their own web applications.

To securely work around this, UCWA leverages an iframe which loads a page from the UCWA API, and then it uses the HTML 5 postMessage function to have it send HTTP requests to that iframe.  You can get more details here: https://ucwa.lync.com/documentation/GettingStarted-CrossDomain

There are other methods for managing cross-origin requests, and this explains how we end up with our OPTIONS request.  A mechanism called Cross-Origin Resource Sharing (CORS) can be used by browsers to authorize the cross-origin request.  You can get details about CORS here: https://www.w3.org/TR/access-control/

If a browsers sees that a cross-origin request is about to occur, it will first perform a preflight request to see if the resource is aware of CORS.  That preflight request takes the form of the OPTIONS request that we see.  Unfortunately UCWA does not support/implement CORS, so this request fails and the startup process terminates.

Since UCWA should be using the iframe, however, why would the browser think a cross-origin request is occurring?  Looking one step back in our trace will give us an answer.

During the UCWA startup process, we reach the point where we make our request to the autodiscover service, and we get our first 401:

GET https://webdir.nnylync.info/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=nnylync.info HTTP/1.1

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer trusted_issuers="", client_id="00000004-0000-0ff1-ce00-000000000000"
WWW-Authenticate: MsRtcOAuth href="https://director.nny.local/WebTicket/oauthtoken",grant_type="urn:microsoft.rtc:windows,urn:microsoft.rtc:passive,urn:microsoft.rtc:anonmeeting,password"

Note that our request here is going to webdir.nnylync.info, however the MsRtcOAuth href in the response is directing us to director.nny.local. For context, webdir.nnylync.info is the external web services FQDN for my director pool, and director.nny.local is the internal web services FQDN for my director pool.

Now this begins to make some sense.  We have an iframe for webdir.nnylync.info, but our next request would be trying to go to director.nny.local which would be cross-domain.

So the real question; why is the MsRtcOAuth href directing us to director.nny.local?

The answer is that it is based on which IIS website we hit on the front end.  Lync has two websites, Lync Server External Web Site, and Lync Server Internal Web Site. The internal website operates on 443.  The external website operates on 4443.  Additionally in the Lync topology you define an internal and external web services FQDN for each pool.

It is expected that requests coming in from the public internet will be going through a reverse proxy which will apply a port translation rule going from 443 to 4443.  Therefore all requests from the public internet should land on the external website, and requests on the internal network can land on the internal website. 

UCWA understands whether it is running on the internal or external side, and this will change which FQDN's get returned in responses.  Since the MsRtcOAuth href contains the internal web services FQDN, that means our request must be landing on the internal website.

In this case, the fact that we hit the internal website while having used the external web services FQDN is the problem.  UCWA is designed to channel all traffic through the external web services FQDN.  This is done for use cases where a device (like a mobile app) could transition from the internal and external networks throughout the day.  In order to keep a consistent connection point for the application, UCWA requires all traffic, both internal and external, to go through the external web site. 

That means that the external web service FQDN resolved by an internal user should still point to the public IP/outside interface IP of the reverse proxy. It should NOT be going directly to the front end server/director IP.

This image, coming from TechNet documentation, shows this scenario well.

You can see these articles for more details regarding this:

https://ucwa.lync.com/documentation/ITAdmin-Architecture

https://technet.microsoft.com/en-us/library/hh690030.aspx

Also, for a small test environment that does not have external access configured, you can work around this problem by simply making the external web services FQDN match the internal web services FQDN in the Lync topology.  Then, regardless of the situation, all connections should land on the Lync internal web site, and since the two web services FQDN's match, there is no cross-domain issue.  This should only be done for test environments, since making this change would cause breaking issues in a production environment where external services are expected to work on the public internet.

Comments

  • Anonymous
    January 01, 2003
    The comment has been removed
  • Anonymous
    February 22, 2015
    The comment has been removed
  • Anonymous
    July 07, 2015
    The comment has been removed