Authentication

Authentication

The Authentication flow is the process of responding to a challenge from the Skype for Business AutoDiscover service and the Lync UCWA Service. A challenge is represented by an HTTP 401 response with a WWW-Authenticate response header field as shown in the following example.

WWW-Authenticate: MsRtcOAuth href=https://contoso.com/WebTicket/oauthtoken,grant_type="urn:microsoft.rtc:windows,urn:microsoft.rtc:anonmeeting,password"

The WWW-Authenticate header contains the following information.

  1. MsRtcOAuth
  2. A link to the OAuth token issuer.
  3. Grant types that are supported.
    • password: The password grant flow contained mandatory username and password parameters. This type of authenication is commonly used in forms-based authentication.
    • urn:microsoft.rtc:windows: This grant type is used when Integrated Windows Authentication (IWA) is used. The request is the same as the password grant, except that username and password parameters must not be present.

      Note: Not all browsers support IWA. Additionally, if your flow contains redirects between domains or servers, the user may be prompted with an authentication dialog window.

    • urn:microsoft.rtc:passive: This grant type is used when any type of passive authentication is used. This works for Active Directory Federation Services-based scenarios and is useful when you need to delegate authentication to other directories. The request is the same as the password grant, except that username and password parameters must not be present.

      Note: For more information about ADFS, see Active Directory Federation Services (AD FS) 2.0. For more information about configuring ADFS with Skype for Business Server, see "Enabling Multi-Factor Authentication for Lync Web App" in Deploying Lync Web App.

    • urn:microsoft.rtc:anonmeeting: This grant type can be used to allow users join meetings anonymously.

Note: the credentials acquired after a 401 challenge apply to the specified URL only. If the user is redirected to a different home server, the redirected URL will likely require a different challenge for new credentials. This could happen when any part of the domain specification (scheme://host:port) changes.

Obtaining a token from the OAuth service

After receiving an HTTP 401 Unauthorized response with a WWW-Authenticate response header, the first step is to choose the grant type and go to the provided link in order to acquire a token.

Password grant type

Request

POST https://contoso.com/WebTicket/oauthtoken HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
.
.
.
grant_type=password&username=johndoe&password=A3ddj3w 
 

Response

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
  "access_token":"cwt=2YotnFZFEjr1zCsicMWpAA...",
  "token_type":"Bearer",
  "expires_in":3600
}
 

Windows grant type

Request

POST https://contoso.com/WebTicket/oauthtoken HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
.
.
.
grant_type=urn:microsoft.rtc:windows
 

Note: Using this grant type might cause a Windows authentication dialog to be displayed, asking the user to enter credentials.

Response

Same as the response for the password grant type.

Anonymous meeting grant type

Request

POST https://contoso.com/WebTicket/oauthtoken HTTP/1.1 
Content-Type: application/x-www-form-urlencoded;charset=UTF-8 
.
.
.
grant_type=urn:microsoft.rtc:anonmeeting&password=G03W98W4&msrtc_conferenceuri=sip%John%contoso.com;gruu;opaque=app:conf:focus:id:G03W98W4 
 

The Anonymous meeting attendee grant type uses two extension parameters: password and msrtc_conferenceuri. The password is the conference key.

The format of the ms_rtc_conferenceuri parameter is:<Organizer SIP URI>; gruu;opaque=app:conf:focus:id:<Conference ID>.

Note: The request body should be URL-encoded.

Response

Same as the response for the password grant type.

Passive grant type

Request

POST https://contoso.com/WebTicket/oauthtoken  HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 36
.
.
.
grant_type=urn:microsoft.rtc:passive

 

Response

HTTP/1.1 400 Bad Request
Content-Type: application/json
X-Ms-diagnostics: 28020;source="server.contoso.com";reason="No valid security token."
X-MS-Server-Fqdn: server.contoso.com
X-Content-Type-Options: nosniff
Content-Length: 134

{"error":"invalid_grant","ms_rtc_passiveauthuri":"https:\/\/server.contoso.com\/PassiveAuth\/PassiveAuth.aspx"}
 

The first request will produce an HTTP 400 Bad Request response if the client does not have an existing ADFS cookie.

The ms_rtc_passiveauthuri parameter provides the application with a link to the secure token service that can issue a token to the application. This service is outside the Skype for Business topologies. Refer to ADFS documentation for acquiring tokens from ADFS.

Using the OAuth token

After the access token is received from the OAuth service, the client application can use the token in requests to the UCWA server using "Bearer" and the OAuth token in the Authorization header as shown in the following example.

Note: For brevity, most of the headers and the request body are omitted here.

POST https://lyncweb.contoso.com/ucwa/oauth/v1/applications HTTP/1.1
Content-Type: application/json
Authorization: Bearer cwt=AAEB....buHc
Host: lyncweb.contoso.com

Note: A token is valid only for a pool. A redirect of a web request to another pool will trigger a new challenge. This does not apply to the Skype for Business AutoDiscover service.

Note: UCWA requires the presence of the Authorization header in each request.

Error conditions

If the request for the access token fails, a 400 response and an error body is returned, similar to the following example.

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
X-Ms-diagnostics: 28029;source="server.contoso.com";reason="Authentication type not allowed."

{
  "error":"unsupported_grant_type",
}

The possible values for "error" are:

  • invalid_request: The request is missing a required parameter, includes an unsupported parameter value (other than grant type), or is otherwise malformed.
  • invalid_grant: The credentials provided could not be verified.
  • unsupported_grant_type: The authorization grant type is not supported by the authorization server.
  • invalid_scope: The requested scope is invalid, unknown, or malformed. The scope property does not need to be sent by the client. As defined by this proposal, the only supported value is "all".
  • server_error: There was an unexpected error on the server that prevented the request from being honored.

Note: It is not recommended that you take a code dependency against the X-Ms-diagnostics header.

If credentials from another pool are supplied, a 500 response will be returned. This could happen when a redirected URL is used without a new challenge for credentials of the redirected pool.

Refreshing an OAuth token

The lifetime of a token is eight (8) hours for authenticated users. The client application should monitor the expiration time and refresh the token as required. Refreshing a token for authenticated users is the same flow as acquiring a new token.

The lifetime of a token for anonymous meeting join is one (1) hour. It is possible to renew to the token by reusing the same token.

The client can use the ms_rtc_renew parameter to pass the original access token. This is necessary so that the anonymous identity originally generated is preserved throughout the meeting.

The following example shows the ms_rtc_renew parameter being used. Note that for brevity, the OAuth token is not entirely shown.

POST https://contoso.com/WebTicket/oauthtoken  HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

grant_type=urn:microsoft.rtc:anonmeeting&password=5LB7MRBC&ms_rtc_conferenceuri=sip:john@contoso.com;gruu;opaque=app:conf:focus:id:5LB7MRBC&ms_rtc_renew=cwt%3dAA...L940

Note: The body content must be URL-encoded.