/// <summary> /// Updates the PhoneWebAuthenticationBroker on the state of the authentication /// operation. If we navigated back by pressing the back key, then the operation /// will be canceled. If the browser control successfully completed the operation, /// signaled by its navigating to the PhoneWebAuthenticationBroker.EndUri, then we /// pass the results on. /// </summary> protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { // If there is an active authentication operation in progress and we have // finished, then we need to inform the authentication broker of the results. // We don't want to stop the operation prematurely, such as when navigating to // the start screen. if (PhoneWebAuthenticationBroker.AuthenticationInProgress && authenticationFinished) { authenticationStarted = false; authenticationFinished = false; PhoneWebAuthenticationBroker.OnAuthenticationFinished(responseData, responseStatus, responseErrorDetail); } }
/// <summary> /// Log a user into a Mobile Services application given a provider name and optional token object. /// </summary> /// <param name="provider" type="MobileServiceAuthenticationProvider"> /// Authentication provider to use. /// </param> /// <param name="token" type="JObject"> /// Optional, provider specific object with existing OAuth token to log in with. /// </param> /// <returns> /// Task that will complete when the user has finished authentication. /// </returns> internal async Task <MobileServiceUser> SendLoginAsync(MobileServiceAuthenticationProvider provider, JObject token = null) { if (this.LoginInProgress) { throw new InvalidOperationException(Resources.MobileServiceClient_Login_In_Progress); } if (!Enum.IsDefined(typeof(MobileServiceAuthenticationProvider), provider)) { throw new ArgumentOutOfRangeException("provider"); } string providerName = provider.ToString().ToLower(); this.LoginInProgress = true; try { JToken response = null; if (token != null) { // Invoke the POST endpoint to exchange provider-specific token for a Windows Azure Mobile Services token response = await this.RequestAsync("POST", LoginAsyncUriFragment + "/" + providerName, token); } else { // Use PhoneWebAuthenticationBroker to launch server side OAuth flow using the GET endpoint Uri startUri = new Uri(this.ApplicationUri, LoginAsyncUriFragment + "/" + providerName); Uri endUri = new Uri(this.ApplicationUri, LoginAsyncDoneUriFragment); PhoneAuthenticationResponse result = await PhoneWebAuthenticationBroker.AuthenticateAsync(startUri, endUri); if (result.ResponseStatus == PhoneAuthenticationStatus.ErrorHttp) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.Authentication_Failed, result.ResponseErrorDetail)); } else if (result.ResponseStatus == PhoneAuthenticationStatus.UserCancel) { throw new InvalidOperationException(Resources.Authentication_Canceled); } int i = result.ResponseData.IndexOf("#token="); if (i > 0) { response = JToken.Parse(Uri.UnescapeDataString(result.ResponseData.Substring(i + 7))); } else { i = result.ResponseData.IndexOf("#error="); if (i > 0) { throw new InvalidOperationException(string.Format( CultureInfo.InvariantCulture, Resources.MobileServiceClient_Login_Error_Response, Uri.UnescapeDataString(result.ResponseData.Substring(i + 7)))); } else { throw new InvalidOperationException(Resources.MobileServiceClient_Login_Invalid_Response_Format); } } } // Get the Mobile Services auth token and user data this.currentUserAuthenticationToken = response.Get(LoginAsyncAuthenticationTokenKey).AsString(); this.CurrentUser = new MobileServiceUser(response.Get("user").Get("userId").AsString()); } finally { this.LoginInProgress = false; } return(this.CurrentUser); }