public async Task <HttpStatusCode> SignIn(string userName, string password) { this.userName = userName; this.password = password; this.authenticationType = AuthenticationTypes.Password; try { var opResult = await DiscoverRootResource(this.discoverFromInternalDomain); if (opResult.Resource == null) { UcwaAppUtils.ReportProgress(OnProgressReported, "GetRootResource returns null result.", opResult.HttpStatusCode); return(opResult.HttpStatusCode); } opResult = await GetUserResource(opResult.Resource.GetLinkUri("user"), userName, password, this.authenticationType); if (opResult.Resource == null) { UcwaAppUtils.ReportProgress(OnProgressReported, userName + " cannot be authenticated, with the " + this.authenticationType.ToString() + " grant_type.", opResult.HttpStatusCode); return(opResult.HttpStatusCode); } // Create the UCWA application bound to the specified user opResult = await GetApplicationResource(opResult.Resource); if (opResult.Resource == null) { UcwaAppUtils.ReportProgress(OnProgressReported, "Failed to create the UCWA application resource.", opResult.HttpStatusCode); return(opResult.HttpStatusCode); } this.ApplicationResource = opResult.Resource; UcwaAppUtils.ReportProgress(OnProgressReported, "Succeded in creating the application resource: " + this.ApplicationResource.Uri); // Make me available to receive incoming alerts this.Me = new UcwaAppMe(this); var statusCode = await this.Me.PostMakeMeAvailable("4255552222", "Online", new string[] { "Plain", "Html" }, new string[] { "PhoneAudio", "Messaging" }); if (statusCode != HttpStatusCode.NoContent) { UcwaAppUtils.ReportProgress(OnProgressReported, "Failed to post to makeMeAvailable resource.", statusCode); return(statusCode); } // Get application resource again to receive any updates triggered by the POST request to making me available opResult = await GetApplicationResource(this.ApplicationResource.Uri); if (opResult.Resource == null) { UcwaAppUtils.ReportProgress(OnProgressReported, "Failed to get the updated application resource", opResult.HttpStatusCode); return(opResult.HttpStatusCode); } this.ApplicationResource = opResult.Resource; statusCode = await this.Me.Refresh(); } catch (Exception ex) { UcwaAppUtils.ReportError(OnErrorReported, ex); return(HttpStatusCode.BadRequest); } return(HttpStatusCode.OK); }
private async Task <UcwaHttpOperationResult> GetUserResource(string userResUri, string userName, string password, AuthenticationTypes authType = AuthenticationTypes.Password) { this.IsSignedIn = false; // // First GET user resource to retrieve oAuthToken href. // Expect 401 Unauthorized response as an HTML payload var response = await Transport.GetRequest(userResUri); if (response.StatusCode != HttpStatusCode.Unauthorized && response.StatusCode != HttpStatusCode.OK) { return(new UcwaHttpOperationResult(response.StatusCode, "Failed to GetRequest on " + userResUri)); } if (response.StatusCode == HttpStatusCode.Unauthorized) { // Get OAuth resource for a Web ticket var authHeader = UcwaAppUtils.ConvertWebHeaderCollectionToKeyValuePairs(response.Headers) .Where(a => a.Key == "WWW-Authenticate" && a.Value.Contains("MsRtcOAuth href")) .FirstOrDefault().Value; var oAuthHref = authHeader.Split(',').Where(s => s.Contains("MsRtcOAuth")).FirstOrDefault() .Split('=')[1].Replace("\"", "").Trim(); string requestBody = GetAuthenticationRequestBody(userName, password, authType); // Note: the following PostRequest returns a json payload in the responseData, containing the access token, var cType = "application/x-www-form-urlencoded;charset='utf-8'"; var aType = "application/x-www-form-urlencoded;charset='utf-8'"; response = await Transport.PostRequest(oAuthHref, aType, cType, requestBody); if (response.StatusCode != HttpStatusCode.OK) { return(new UcwaHttpOperationResult(response.StatusCode, "PostRequest on " + oAuthHref + " with " + requestBody)); } string responseData = UcwaAppUtils.ConvertResponseBodyStreamToString(response.GetResponseStream()); if (authType == AuthenticationTypes.Passive && response.StatusCode == HttpStatusCode.BadRequest && responseData.Contains("ms_rtc_passiveauthuri")) { // get ms_rtc_passiveauthuri to obtain an ADFS cookie and do another POST request (above) to obtain UCWA oAuth token System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex("\"ms_rtc_passiveauthuri\":\"(.)\""); var match = regex.Match(responseData); var passiveauthuri = match.Groups[1].Value; // to do: obtain a token from ADFS // ... .// omitted here // repost on oAuthHref, once a new ADFS token is had response = await Transport.PostRequest(oAuthHref, aType, cType, requestBody); if (response.StatusCode != HttpStatusCode.OK) { return(new UcwaHttpOperationResult(response.StatusCode, "PostRequest on " + oAuthHref + " with " + requestBody)); } responseData = UcwaAppUtils.ConvertResponseBodyStreamToString(response.GetResponseStream()); } // Extract the access token from the response body to construct the oAuth token oAuth20Token = GetOAuthToken(responseData); if (oAuth20Token != null) { Transport.OAuthToken = oAuth20Token; // Second GET userHref, supplying the required compact-web-ticket (cwt) in an Authorization header response = await Transport.GetRequest(userResUri); if (response.StatusCode != HttpStatusCode.OK) { return(new UcwaHttpOperationResult(response.StatusCode, "GetRequest on " + userResUri + " with oAuth token of " + oAuth20Token)); } } else { return(new UcwaHttpOperationResult(response.StatusCode, "PostRequest on " + oAuthHref + " returns " + responseData)); } } this.IsSignedIn = true; var res = new UcwaResource(response.GetResponseStream()); return(new UcwaHttpOperationResult(response.StatusCode, null, res)); }