private void WireMessages()
        {
            Messenger.Default.Register<NotificationMessage>(this, async m =>
                                                                      {
                                                                          if (m.Notification.Equals("AccountViewLoaded") || m.Notification.Equals("AppLoaded"))
                                                                          {
                                                                              try
                                                                              {
                                                                                  if (_navigationService.IsNetworkAvailable)
                                                                                  {
                                                                                      _liveLoginResult = await _authClient.InitializeAsync(LiveSDKClientHelper.GetScopesStringList(_scopes));

                                                                                      IsLoggedIn = _liveLoginResult.Status == LiveConnectSessionStatus.Connected;

                                                                                      await GetLoginDetails();
                                                                                  }
                                                                              }
                                                                              catch{}
                                                                          }

                                                                          if (m.Notification.Equals("Logout"))
                                                                          {
                                                                              if (_authClient.CanLogout)
                                                                              {
                                                                                  _authClient.Logout();
                                                                                  IsLoggedIn = false;
                                                                                  LoggedInAs = "Not logged in";
                                                                              }
                                                                              else
                                                                              {
                                                                                  await MessageBox.ShowAsync("We were unable to sign you out at this time", "Unable to sign out", MessageBoxButton.OK);
                                                                              }
                                                                          }
                                                                      });
        }
        /// <summary>
        /// Initializes the LiveAuthClient instance by trying to retrieve an access token using refresh token
        /// provided by the app via the IRefreshTokenHandler instance.
        /// </summary>
        public Task<LiveLoginResult> InitializeAsync(IEnumerable<string> scopes)
        {
            // We don't allow InitializeAsync or ExchangeAuthCodeAsync to be invoked concurrently.
            if (this.initTask != null)
            {
                throw new InvalidOperationException(ErrorText.ExistingAuthTaskRunning);
            }

            var task = new TaskCompletionSource<LiveLoginResult>();
            this.initTask = task;
            this.initScopes = scopes;

            if (this.loginStatus != null)
            {
                // We have a result already, then return this one.
                this.OnInitCompleted(null);
            }
            else
            {
                this.loginStatus = new LiveLoginResult(LiveConnectSessionStatus.Unknown, null);
                this.TryRefreshToken();
            }

            return task.Task;
        }
Beispiel #3
0
 //인스턴스 생성용 method
 private async void login_Client()
 {
     try
     {
         //Client 생성
         authClient = new LiveAuthClient();
         //초기화
         result = await authClient.InitializeAsync();
         //로그인
         loginResult = await authClient.LoginAsync(scope);
         //로그인 할 떄 cancel을 누르면 뒤로 돌아가기
     }
     catch (NullReferenceException ex)
     {
         //로그인 할 때 cancel을 누르면 nullreferenceException 발생
         //뒤로가기
         ex.Message.ToString();
         messagePrint(false);
         if (Frame.CanGoBack)
         {
             Frame.GoBack();
         }
     }
     catch (Exception ex)
     {
         //기타 Exception을 위한 catch
         ex.Message.ToString();
         messagePrint(false);
         if(Frame.CanGoBack)
         {
             Frame.GoBack();
         }
     }
 }
        /// <summary>
        /// Authenticate the user.  Ask user for consent if neccessary.
        /// </summary>
        public async Task<LiveLoginResult> AuthenticateAsync(string scopes, bool? silent)
        {
            Exception error = null;
            string accessToken = null;
            string authenticationToken = null;

            LiveLoginResult result = null;

            try
            {
                accessToken = await this.GetAccessToken(scopes, silent);
                LiveConnectSession session = new LiveConnectSession(this.authClient);
                session.AccessToken = accessToken;

                if (!string.IsNullOrEmpty(this.authClient.RedirectUrl) &&
                    !this.authClient.RedirectUrl.Equals(Win8ReturnUriScheme, StringComparison.OrdinalIgnoreCase))
                {
                    authenticationToken = await this.GetAuthenticationToken(this.authClient.RedirectUrl, silent);
                    session.AuthenticationToken = authenticationToken;
                }

                result = new LiveLoginResult(LiveConnectSessionStatus.Connected, session);
            }
            catch (TaskCanceledException)
            {
                result = new LiveLoginResult(LiveConnectSessionStatus.NotConnected, null);
            }
            catch (Exception comExp)
            {
                switch (comExp.HResult)
                {
                    case TailoredAuthClient.UserNotFoundLoginExceptionHResult:
                        result = new LiveLoginResult(LiveConnectSessionStatus.Unknown, null);
                        break;
                    case TailoredAuthClient.ConsentNotGrantedExceptionHResult:
                        result = new LiveLoginResult(LiveConnectSessionStatus.NotConnected, null);
                        break;
                    case TailoredAuthClient.InvalidClientExceptionHResult:
                    case TailoredAuthClient.InvalidAuthTargetExceptionHResult:
                        error = new LiveAuthException(AuthErrorCodes.InvalidRequest, ResourceHelper.GetString("InvalidAuthClient"), comExp);
                        break;
                    default:
                        error = new LiveAuthException(AuthErrorCodes.ServerError, ResourceHelper.GetString("ServerError"), comExp);
                        break;
                }
            }

            if (result == null)
            {
                Debug.Assert(error != null);

                result = new LiveLoginResult(error);
            }

            return result;
        }
        //private static Task<LiveLoginResult> RequestAccessTokenAsync(string postContent)
        //{
        //    Task<LiveLoginResult> task = Task.Factory.StartNew(() =>
        //    {
        //        return RequestAccessToken(postContent);
        //    });

        //    return task;
        //}

        private static async Task<LiveLoginResult> RequestAccessTokenAsync(string postContent)
        {
            string url = LiveAuthUtility.BuildTokenUrl();
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            HttpWebResponse response = null;
            LiveLoginResult loginResult = null;
            request.Method = ApiMethod.Post.ToString().ToUpperInvariant();
            request.ContentType = TokenRequestContentType;

            try
            {
                var requestStream = await request.GetRequestStreamAsync();
                using (StreamWriter writer = new StreamWriter(requestStream))
                {
                    writer.Write(postContent);
                }

                response = await request.GetResponseAsync() as HttpWebResponse;
                loginResult = ReadResponse(response);
            }
            catch (WebException e)
            {
                response = e.Response as HttpWebResponse;
                loginResult = ReadResponse(response);
            }
            catch (IOException ioe)
            {
                loginResult = new LiveLoginResult(new LiveAuthException(AuthErrorCodes.ClientError, ioe.Message));
            }
            finally
            {
                if (response != null)
                {
                    //response.Close();
                    response.Dispose();
                }
            }

            if (loginResult == null)
            {
                loginResult = new LiveLoginResult(new LiveAuthException(AuthErrorCodes.ClientError, ErrorText.RetrieveTokenError));
            }

            return loginResult;
        }
Beispiel #6
0
        private static LiveLoginResult RequestAccessToken(string postContent)
        {
            string          url         = LiveAuthUtility.BuildTokenUrl();
            HttpWebRequest  request     = WebRequest.Create(url) as HttpWebRequest;
            HttpWebResponse response    = null;
            LiveLoginResult loginResult = null;

            request.Method      = ApiMethod.Post.ToString().ToUpperInvariant();
            request.ContentType = TokenRequestContentType;

            try
            {
                using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
                {
                    writer.Write(postContent);
                }

                response    = request.GetResponse() as HttpWebResponse;
                loginResult = ReadResponse(response);
            }
            catch (WebException e)
            {
                response    = e.Response as HttpWebResponse;
                loginResult = ReadResponse(response);
            }
            catch (IOException ioe)
            {
                loginResult = new LiveLoginResult(new LiveAuthException(AuthErrorCodes.ClientError, ioe.Message));
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }

            if (loginResult == null)
            {
                loginResult = new LiveLoginResult(new LiveAuthException(AuthErrorCodes.ClientError, ErrorText.RetrieveTokenError));
            }

            return(loginResult);
        }
        public override async Task<AuthenticationResult> AuthenticateAsync()
        {
            var result = await _authClient.LoginAsync(this.AuthorizationScopesList.ToArray());
            if (result != null && result.Status == LiveConnectSessionStatus.Connected)
            {
                _result = result;
                return AuthenticationResult.Success;
            }
            if (result.Status == LiveConnectSessionStatus.Unknown)
                return AuthenticationResult.Unknown;
            else if (result.Status == LiveConnectSessionStatus.NotConnected)
                return AuthenticationResult.Failed;

            return AuthenticationResult.Unknown;
            //A really bad status to talk about!
            //var client = new LiveConnectClient(result.Session);
            //dynamic result2 = await client.GetAsync("me/skydrive/files");

        }
        protected async override Task OnActivate()
        {
            if (authClient == null)
            {
                authClient = new LiveAuthClient(ApiKeys.SkyDriveClientId);

                IEnumerable<string> scopes = ParseScopeString(Scopes);

                try
                {
                    Task<LiveLoginResult> result = authClient.InitializeAsync(scopes);
                    LiveLoginResult = await result;                   
                }
                catch (Exception exception)
                {
                    //this.RaiseSessionChangedEvent(new LiveConnectSessionChangedEventArgs(exception));
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Parse the response data.
        /// </summary>
        private LiveLoginResult ParseResponseFragment(string fragment)
        {
            Debug.Assert(!string.IsNullOrEmpty(fragment));

            LiveLoginResult loginResult         = null;
            IDictionary <string, object> result = LiveAuthClient.ParseQueryString(fragment);

            if (result.ContainsKey(AuthConstants.AccessToken))
            {
                LiveConnectSession sessionData = CreateSession(this, result);

                loginResult = new LiveLoginResult(LiveConnectSessionStatus.Connected, sessionData);
            }
            else if (result.ContainsKey(AuthConstants.Error))
            {
                loginResult = GetErrorResult(result);
            }

            return(loginResult);
        }
        private void OnInitCompleted(LiveLoginResult authResult)
        {
            authResult = this.ValidateSessionInitScopes(authResult);
            this.UpdateSession(authResult);

            Debug.Assert(this.loginStatus != null);
            this.publicAuthClient.FirePendingPropertyChangedEvents();


            if (authResult != null && authResult.Error != null)
            {
                this.initTask.SetException(authResult.Error);
            }
            else
            {
                this.initTask.SetResult(this.loginStatus);
            }

            this.initTask = null;
        }
 private void RefreshToken(Action <LiveLoginResult> completionCallback)
 {
     if (this.refreshTokenInfo != null)
     {
         LiveAuthRequestUtility.RefreshTokenAsync(
             this.clientId,
             null,
             LiveAuthUtility.BuildDesktopRedirectUrl(),
             this.refreshTokenInfo.RefreshToken,
             null     /*scopes*/
             ).ContinueWith(t =>
         {
             this.OnRefreshTokenCompleted(t.Result, completionCallback);
         });
     }
     else
     {
         LiveLoginResult result = new LiveLoginResult(LiveConnectSessionStatus.Unknown, null);
         this.OnRefreshTokenCompleted(result, completionCallback);
     }
 }
        internal void TryRefreshToken(Action <LiveLoginResult> completionCallback)
        {
            LiveLoginResult result = new LiveLoginResult(LiveConnectSessionStatus.Unknown, null);

            if (this.refreshTokenHandler != null)
            {
                if (this.refreshTokenInfo == null)
                {
                    this.refreshTokenHandler.RetrieveRefreshTokenAsync().ContinueWith(t =>
                    {
                        this.refreshTokenInfo = t.Result;
                        this.RefreshToken(completionCallback);
                    });
                    return;
                }

                this.RefreshToken(completionCallback);
                return;
            }

            this.OnRefreshTokenCompleted(result, completionCallback);
        }
Beispiel #13
0
        private void CompleteAuthTask(LiveLoginResult loginResult)
        {
            Debug.Assert(loginResult != null);

            loginResult = this.ValidateSessionInitScopes(loginResult);
            HttpContextUtility.UpdateUserSession(this.webContext, loginResult, this.appRequestTs);

            if (loginResult.Session != null)
            {
                // Only update Session property if there is a new session.
                this.publicAuthClient.Session = loginResult.Session;
            }

            this.publicAuthClient.FirePendingPropertyChangedEvents();

            TaskCompletionSource <LiveLoginResult> taskSource = this.currentTask;

            if (taskSource != null)
            {
                this.currentTask = null;

                if (loginResult.Error != null)
                {
                    var error = loginResult.Error as LiveAuthException;
                    if (error == null)
                    {
                        error = new LiveAuthException(AuthErrorCodes.ClientError, error.Message, loginResult.Error);
                    }

                    error.State = this.appRequestState;
                    taskSource.SetException(loginResult.Error);
                }
                else
                {
                    loginResult.State = this.appRequestState;
                    taskSource.SetResult(loginResult);
                }
            }
        }
Beispiel #14
0
        private async void TryRefreshToken(Action <LiveLoginResult> completionCallback)
        {
            LiveLoginResult result = await this.AuthClient.AuthenticateAsync(
                LiveAuthClient.BuildScopeString(this.currentScopes),
                true);

            if (result.Status == LiveConnectSessionStatus.NotConnected &&
                this.currentScopes.Count > 1)
            {
                // The user might have revoked one of the scopes while the app is running. Try getting a token for the remaining scopes
                // by passing in only the "wl.signin" scope. The server should return a token that contains all remaining scopes.
                this.currentScopes = new List <string>(new string[] { LiveAuthClient.SignInOfferName });
                result             = await this.AuthClient.AuthenticateAsync(
                    LiveAuthClient.BuildScopeString(this.currentScopes),
                    true);
            }

            if (result.Session != null && !AreSessionsSame(this.Session, result.Session))
            {
                this.Session = result.Session;
            }

            completionCallback(result);
        }
        /// <summary>
        /// Authenticate the user.  Ask user for consent if neccessary.
        /// </summary>
        public async Task <LiveLoginResult> AuthenticateAsync(string scopes, bool silent)
        {
            Exception error               = null;
            string    accessToken         = null;
            string    authenticationToken = null;

            LiveLoginResult result = null;

            try
            {
                accessToken = await this.GetAccessToken(scopes, silent);

                LiveConnectSession session = new LiveConnectSession(this.authClient);
                session.AccessToken = accessToken;

                if (!string.IsNullOrEmpty(this.authClient.RedirectUrl) &&
                    !this.authClient.RedirectUrl.StartsWith(Win8AppIdPrefix, StringComparison.OrdinalIgnoreCase))
                {
                    authenticationToken = await this.GetAuthenticationToken(this.authClient.RedirectUrl, silent);

                    session.AuthenticationToken = authenticationToken;
                }

                result = new LiveLoginResult(LiveConnectSessionStatus.Connected, session);
            }
            catch (TaskCanceledException)
            {
                result = new LiveLoginResult(LiveConnectSessionStatus.NotConnected, null);
            }
            catch (Exception comExp)
            {
                switch (comExp.HResult)
                {
                case TailoredAuthClient.UserNotFoundLoginExceptionHResult:
                    result = new LiveLoginResult(LiveConnectSessionStatus.Unknown, null);
                    break;

                case TailoredAuthClient.ConsentNotGrantedExceptionHResult:
                    result = new LiveLoginResult(LiveConnectSessionStatus.NotConnected, null);
                    break;

                case TailoredAuthClient.InvalidClientExceptionHResult:
                case TailoredAuthClient.InvalidAuthTargetExceptionHResult:
                    error = new LiveAuthException(AuthErrorCodes.InvalidRequest, ResourceHelper.GetString("InvalidAuthClient"), comExp);
                    break;

                default:
                    error = new LiveAuthException(AuthErrorCodes.ServerError, ResourceHelper.GetString("ServerError"), comExp);
                    break;
                }
            }

            if (result == null)
            {
                Debug.Assert(error != null);

                result = new LiveLoginResult(error);
            }

            return(result);
        }
        /// <summary>
        /// Writes the user current session.
        /// </summary>
        public static void UpdateUserSession(HttpContextBase context, LiveLoginResult loginResult, string requestTs)
        {
            if (context == null)
            {
                return;
            }

            Debug.Assert(loginResult != null);

            Dictionary<string, string> cookieValues = new Dictionary<string, string>();
            HttpCookie cookie = context.Request.Cookies[AuthCookie];
            HttpCookie newCookie = new HttpCookie(AuthCookie);
            newCookie.Path = "/";
            string host = context.Request.Headers["Host"];
            newCookie.Domain = host.Split(':')[0];

            if (cookie != null && cookie.Values != null)
            {
                foreach (string key in cookie.Values.AllKeys)
                {
                    newCookie.Values[key] = cookie[key];
                }
            }

            LiveConnectSession session = loginResult.Session;
            if (session != null)
            {
                newCookie.Values[AuthConstants.AccessToken] = Uri.EscapeDataString(session.AccessToken);
                newCookie.Values[AuthConstants.AuthenticationToken] = Uri.EscapeDataString(session.AuthenticationToken);
                newCookie.Values[AuthConstants.Scope] = Uri.EscapeDataString(LiveAuthUtility.BuildScopeString(session.Scopes));
                newCookie.Values[AuthConstants.ExpiresIn] = Uri.EscapeDataString(LiveAuthWebUtility.GetExpiresInString(session.Expires));
                newCookie.Values[AuthConstants.Expires] = Uri.EscapeDataString(LiveAuthWebUtility.GetExpiresString(session.Expires));
            }

            LiveConnectSessionStatus status;
            if (!string.IsNullOrEmpty(newCookie[AuthConstants.AccessToken]))
            {
                // We have an access token, so it is connected, regardless expired or not 
                // since it is handled after loading the session in both Asp.Net and JS library.
                status = LiveConnectSessionStatus.Connected;
            }
            else
            {
                status = loginResult.Status;
                if (loginResult.Status == LiveConnectSessionStatus.Unknown)
                {
                    // If we recorded NotConnected previously, keep it.
                    LiveConnectSessionStatus statusFromCookie;
                    if (Enum.TryParse<LiveConnectSessionStatus>(
                            newCookie[AuthConstants.Status], 
                            true/*ignore case*/, 
                            out statusFromCookie))
                    {
                        if (statusFromCookie == LiveConnectSessionStatus.NotConnected)
                        {
                            status = statusFromCookie;
                        }
                    }
                }
            }

            newCookie.Values[AuthConstants.Status] = GetStatusString(status);

            // Needs to write error to inform the JS library.
            LiveAuthException authError = loginResult.Error as LiveAuthException;
            if (authError != null)
            {
                newCookie.Values[AuthConstants.Error] = Uri.EscapeDataString(authError.ErrorCode);
                newCookie.Values[AuthConstants.ErrorDescription] = HttpUtility.UrlPathEncode(authError.Message);
            }
            else if (status != LiveConnectSessionStatus.Connected)
            {
                newCookie.Values[AuthConstants.Error] = Uri.EscapeDataString(AuthErrorCodes.AccessDenied);
                newCookie.Values[AuthConstants.ErrorDescription] = HttpUtility.UrlPathEncode("Cannot retrieve access token.");
            }

            if (!string.IsNullOrEmpty(requestTs))
            {
                newCookie.Values[AuthConstants.ClientRequestTs] = requestTs;
            }

            context.Response.Cookies.Add(newCookie);
        }
        private void TryRefreshToken(string redirectUrl)
        {
            Debug.Assert(this.loginStatus != null);

            IEnumerable<string> scopes;
            LiveAuthException error;
            bool isTokenRequest = this.CheckRefreshTokenRequest(out scopes, out error);
            if (error != null)
            {
                this.OnAuthTaskCompleted(new LiveLoginResult(error));
                return;
            }

            // Try to refresh a token if 
            // i) there is a token request or
            // ii) we don't have a token or 
            // iii) the current token is expired.    
            LiveLoginResult result = null;
            LiveConnectSession session = this.loginStatus.Session;
            bool hasValidToken = session != null && session.IsValid;
            bool shouldRefresh = (this.refreshTokenHandler != null) && (isTokenRequest || !hasValidToken);

            if (!shouldRefresh)
            {
                this.OnAuthTaskCompleted(null);
                return;
            }

            if (this.initScopes == null)
            {
                // We don't have initScopes, then use the scopes received from Url.
                this.initScopes = scopes;
            }

            this.refreshTokenHandler.RetrieveRefreshTokenAsync().ContinueWith(t =>
            {
                try
                {
                    this.refreshTokenInfo = t.Result;
                    if (this.refreshTokenInfo != null)
                    {
                        string currentUserId = this.publicAuthClient.CurrentUserId;
                        if (currentUserId != null && this.refreshTokenInfo.UserId != currentUserId)
                        {
                            // There is a user Id available in current session. We need to ensure the token provided matches it.
                            result = new LiveLoginResult(new LiveAuthException(
                                AuthErrorCodes.InvalidRequest, ErrorText.RefereshTokenNotMatchUserId));
                        }
                        else
                        {
                            LiveAuthRequestUtility.RefreshTokenAsync(
                               this.clientId,
                               this.clientSecret,
                               redirectUrl,
                               this.refreshTokenInfo.RefreshToken,
                               null/*scopes -  We intentially specify null scopes and validate the initScopes after we have the session 
                                    * result. With this approach, we can return notConnected if initScopes is not satisfied, and surface
                                    * the error if there is one.
                                    */
                               ).ContinueWith((Task<LiveLoginResult> rt) =>
                            {
                                result = rt.Result;
                                this.OnAuthTaskCompleted(result);
                            });
                            return;
                        }
                    }
                }
                catch (Exception ex)
                {
                    error = new LiveAuthException(AuthErrorCodes.ClientError, ErrorText.RetrieveRefreshTokenError, ex);
                    result = new LiveLoginResult(error);
                }

                this.OnAuthTaskCompleted(result);
            });
        }
Beispiel #18
0
        /// <summary>
        /// Writes the user current session.
        /// </summary>
        public static void UpdateUserSession(HttpContextBase context, LiveLoginResult loginResult, string requestTs)
        {
            if (context == null)
            {
                return;
            }

            Debug.Assert(loginResult != null);

            Dictionary <string, string> cookieValues = new Dictionary <string, string>();
            HttpCookie cookie    = context.Request.Cookies[AuthCookie];
            HttpCookie newCookie = new HttpCookie(AuthCookie);

            newCookie.Path = "/";
            string host = context.Request.Headers["Host"];

            newCookie.Domain = host.Split(':')[0];

            if (cookie != null && cookie.Values != null)
            {
                foreach (string key in cookie.Values.AllKeys)
                {
                    newCookie.Values[key] = cookie[key];
                }
            }

            LiveConnectSession session = loginResult.Session;

            if (session != null)
            {
                newCookie.Values[AuthConstants.AccessToken]         = Uri.EscapeDataString(session.AccessToken);
                newCookie.Values[AuthConstants.AuthenticationToken] = Uri.EscapeDataString(session.AuthenticationToken);
                newCookie.Values[AuthConstants.Scope]     = Uri.EscapeDataString(LiveAuthUtility.BuildScopeString(session.Scopes));
                newCookie.Values[AuthConstants.ExpiresIn] = Uri.EscapeDataString(LiveAuthWebUtility.GetExpiresInString(session.Expires));
                newCookie.Values[AuthConstants.Expires]   = Uri.EscapeDataString(LiveAuthWebUtility.GetExpiresString(session.Expires));
            }

            LiveConnectSessionStatus status;

            if (!string.IsNullOrEmpty(newCookie[AuthConstants.AccessToken]))
            {
                // We have an access token, so it is connected, regardless expired or not
                // since it is handled after loading the session in both Asp.Net and JS library.
                status = LiveConnectSessionStatus.Connected;
            }
            else
            {
                status = loginResult.Status;
                if (loginResult.Status == LiveConnectSessionStatus.Unknown)
                {
                    // If we recorded NotConnected previously, keep it.
                    LiveConnectSessionStatus statusFromCookie;
                    if (Enum.TryParse <LiveConnectSessionStatus>(
                            newCookie[AuthConstants.Status],
                            true /*ignore case*/,
                            out statusFromCookie))
                    {
                        if (statusFromCookie == LiveConnectSessionStatus.NotConnected)
                        {
                            status = statusFromCookie;
                        }
                    }
                }
            }

            newCookie.Values[AuthConstants.Status] = GetStatusString(status);

            // Needs to write error to inform the JS library.
            LiveAuthException authError = loginResult.Error as LiveAuthException;

            if (authError != null)
            {
                newCookie.Values[AuthConstants.Error]            = Uri.EscapeDataString(authError.ErrorCode);
                newCookie.Values[AuthConstants.ErrorDescription] = HttpUtility.UrlPathEncode(authError.Message);
            }
            else if (status != LiveConnectSessionStatus.Connected)
            {
                newCookie.Values[AuthConstants.Error]            = Uri.EscapeDataString(AuthErrorCodes.AccessDenied);
                newCookie.Values[AuthConstants.ErrorDescription] = HttpUtility.UrlPathEncode("Cannot retrieve access token.");
            }

            if (!string.IsNullOrEmpty(requestTs))
            {
                newCookie.Values[AuthConstants.ClientRequestTs] = requestTs;
            }

            context.Response.Cookies.Add(newCookie);
        }
Beispiel #19
0
        /// <summary>
        /// Downloads the resource with the given path to the downloadLocation using the Windows Phone
        /// BackgroundTransferService.
        /// </summary>
        /// <param name="path">Path to the resource to download</param>
        /// <param name="downloadLocation">
        ///     The path to the file that will contain the download resource.
        ///     The downloadLocation must exist in /shared/transfers.
        /// </param>
        /// <param name="ct">a token that is used to cancel the background download operation.</param>
        /// <param name="progress">an object that is called to report the background download's progress.</param>
        /// <returns>A Task object representing the asynchronous operation.</returns>
        public async Task <LiveOperationResult> BackgroundDownloadAsync(
            string path,
            Uri downloadLocation,
            CancellationToken ct,
            IProgress <LiveOperationProgress> progress)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UrlInvalid"),
                                               "path");
                if (path == null)
                {
                    throw new ArgumentNullException("path", message);
                }

                throw new ArgumentException(message, "path");
            }

            if (downloadLocation == null)
            {
                throw new ArgumentNullException("downloadLocation");
            }

            string filename = Path.GetFileName(downloadLocation.OriginalString);

            if (string.IsNullOrEmpty(filename))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UriMissingFileName"),
                                               "downloadLocation");
                throw new ArgumentException(message, "downloadLocation");
            }

            if (!BackgroundTransferHelper.IsRootedInSharedTransfers(downloadLocation))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UriMustBeRootedInSharedTransfers"),
                                               "downloadLocation");
                throw new ArgumentException(message, "downloadLocation");
            }

            if (this.Session == null)
            {
                throw new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("UserNotLoggedIn"));
            }

            Uri requestUri = this.GetResourceUri(path, ApiMethod.Download);

            var builder = new BackgroundDownloadOperation.Builder
            {
                RequestUri = requestUri,
                DownloadLocationOnDevice  = downloadLocation,
                BackgroundTransferService = this.BackgroundTransferService,
                Progress = progress,
                BackgroundTransferPreferences = this.BackgroundTransferPreferences
            };

            if (!this.Session.IsValid)
            {
                LiveLoginResult result = await this.Session.AuthClient.RefreshTokenAsync();

                if (result.Status == LiveConnectSessionStatus.Connected)
                {
                    this.Session = result.Session;
                }
            }

            builder.AccessToken = this.Session.AccessToken;

            BackgroundDownloadOperation operation = builder.Build();

            ct.Register(operation.Cancel);

            return(await operation.ExecuteAsync());
        }
        private LiveLoginResult ValidateSessionInitScopes(LiveLoginResult loginResult)
        {
            if (loginResult.Session != null && this.initScopes != null)
            {
                if (!LiveAuthUtility.IsSubsetOfScopeRange(this.initScopes, loginResult.Session.Scopes))
                {
                    loginResult = new LiveLoginResult(LiveConnectSessionStatus.NotConnected, null);
                }

                this.initScopes = null;
            }

            return loginResult;
        }
 private void RefreshToken(Action<LiveLoginResult> completionCallback)
 {
     if (this.refreshTokenInfo != null)
     {
         LiveAuthRequestUtility.RefreshTokenAsync(
                 this.clientId,
                 null,
                 LiveAuthUtility.BuildDesktopRedirectUrl(),
                 this.refreshTokenInfo.RefreshToken,
                 null /*scopes*/
             ).ContinueWith(t =>
             {
                 this.OnRefreshTokenCompleted(t.Result, completionCallback);
             });
     }
     else
     {
         LiveLoginResult result = new LiveLoginResult(LiveConnectSessionStatus.Unknown, null);
         this.OnRefreshTokenCompleted(result, completionCallback);
     }
 }
        private void OnInitCompleted(LiveLoginResult authResult)
        {
            authResult = this.ValidateSessionInitScopes(authResult);
            this.UpdateSession(authResult);

            Debug.Assert(this.loginStatus != null);
            this.publicAuthClient.FirePendingPropertyChangedEvents();

            if (authResult != null && authResult.Error != null)
            {
                this.initTask.SetException(authResult.Error);
            }
            else
            {
                this.initTask.SetResult(this.loginStatus);
            }

            this.initTask = null;
        }
        internal void TryRefreshToken(Action<LiveLoginResult> completionCallback)
        {
            LiveLoginResult result = new LiveLoginResult(LiveConnectSessionStatus.Unknown, null);
            if (this.refreshTokenHandler != null)
            {
                if (this.refreshTokenInfo == null)
                {
                    this.refreshTokenHandler.RetrieveRefreshTokenAsync().ContinueWith(t =>
                    {
                        this.refreshTokenInfo = t.Result;
                        this.RefreshToken(completionCallback);

                    });
                    return;
                }

                this.RefreshToken(completionCallback);
                return;
            }

            this.OnRefreshTokenCompleted(result, completionCallback);
        }
Beispiel #24
0
        private void TryRefreshToken(string redirectUrl)
        {
            Debug.Assert(this.loginStatus != null);

            IEnumerable <string> scopes;
            LiveAuthException    error;
            bool isTokenRequest = this.CheckRefreshTokenRequest(out scopes, out error);

            if (error != null)
            {
                this.OnAuthTaskCompleted(new LiveLoginResult(error));
                return;
            }

            // Try to refresh a token if
            // i) there is a token request or
            // ii) we don't have a token or
            // iii) the current token is expired.
            LiveLoginResult    result  = null;
            LiveConnectSession session = this.loginStatus.Session;
            bool hasValidToken         = session != null && session.IsValid;
            bool shouldRefresh         = (this.refreshTokenHandler != null) && (isTokenRequest || !hasValidToken);

            if (!shouldRefresh)
            {
                this.OnAuthTaskCompleted(null);
                return;
            }

            if (this.initScopes == null)
            {
                // We don't have initScopes, then use the scopes received from Url.
                this.initScopes = scopes;
            }

            this.refreshTokenHandler.RetrieveRefreshTokenAsync().ContinueWith(t =>
            {
                try
                {
                    this.refreshTokenInfo = t.Result;
                    if (this.refreshTokenInfo != null)
                    {
                        string currentUserId = this.publicAuthClient.CurrentUserId;
                        if (currentUserId != null && this.refreshTokenInfo.UserId != currentUserId)
                        {
                            // There is a user Id available in current session. We need to ensure the token provided matches it.
                            result = new LiveLoginResult(new LiveAuthException(
                                                             AuthErrorCodes.InvalidRequest, ErrorText.RefereshTokenNotMatchUserId));
                        }
                        else
                        {
                            LiveAuthRequestUtility.RefreshTokenAsync(
                                this.clientId,
                                this.clientSecret,
                                redirectUrl,
                                this.refreshTokenInfo.RefreshToken,
                                null/*scopes -  We intentially specify null scopes and validate the initScopes after we have the session
                                     * result. With this approach, we can return notConnected if initScopes is not satisfied, and surface
                                     * the error if there is one.
                                     */
                                ).ContinueWith((Task <LiveLoginResult> rt) =>
                            {
                                result = rt.Result;
                                this.OnAuthTaskCompleted(result);
                            });
                            return;
                        }
                    }
                }
                catch (Exception ex)
                {
                    error  = new LiveAuthException(AuthErrorCodes.ClientError, ErrorText.RetrieveRefreshTokenError, ex);
                    result = new LiveLoginResult(error);
                }

                this.OnAuthTaskCompleted(result);
            });
        }
        private void OnLogin(LiveLoginResult loginResult)
        {
            Session = loginResult.Session;


            if (loginResult.Status == LiveConnectSessionStatus.Connected)
            {
                _cache.SkydriveSession = loginResult.Session;
                _navigationService.UriFor<BrowseCloudFilesViewModel>()
                    .WithParam(vm => vm.CloudProvider, CloudProvider.SkyDrive)
                    .WithParam(vm => vm.NavigationUrl, "/me/skydrive")
                    .Navigate();
            }
            else
            {
                _cache.SkydriveSession = null;
                SignInIsEnabled = true;
            }        
        }
        private void OnExchangeCodeCompleted(LiveLoginResult authResult)
        {
            this.UpdateSession(authResult);

            Debug.Assert(this.loginStatus != null);
            this.publicAuthClient.FirePendingPropertyChangedEvents();
            if (authResult != null && authResult.Error != null)
            {
                this.codeExchangeTask.SetException(authResult.Error);
            }
            else
            {
                this.codeExchangeTask.SetResult(authResult.Session);
            }

            this.codeExchangeTask = null;
        }
        /// <summary>
        /// Initializes the LiveAuthClient instance for the current user. 
        /// If an authorization code is present, it will send a request to the auth server to exchange the token.
        /// If there is an auth session in current context, it will retrieve the current auth session.
        /// If the current session is expired or the current request url indicates (refresh=1) to get a new token, 
        /// it will try to request a new access token using refresh token that will need to be provided through 
        /// IRefreshTokenHandler.RetrieveRefreshTokenAsync() method.
        /// Any updated session state will be saved in the auth session cookie.
        /// </summary>
        public Task<LiveLoginResult> ExchangeAuthCodeAsync(string redirectUrl, HttpContextBase webContext)
        {
            Debug.Assert(webContext != null);
            Debug.Assert(!string.IsNullOrEmpty(redirectUrl));

            this.ValidateConflictAuthTask();

            this.webContext = webContext;
            var taskSource = new TaskCompletionSource<LiveLoginResult>();
            this.currentTask = taskSource;

            string authorizationCode;
            LiveAuthException error;
            this.LoadSession(out authorizationCode, out error);

            // If this page receives an authorization code, then exchange the code
            // with the auth server to get the tokens.
            if (!string.IsNullOrEmpty(authorizationCode))
            {
                // We intentionally move auth actions into a wrapping asynchronous process to work around an issue where
                // invoking Task Async methods will trigger an error to be thrown on an Async Asp.Net page (.aspx) code.
                Task.Factory.StartNew(() =>
                {
                    this.ExchangeCodeForToken(
                        redirectUrl,
                        authorizationCode);
                });
            }
            else if (error != null)
            {
                // We received error from the auth server response.
                if (error.ErrorCode == AuthErrorCodes.AccessDenied)
                {
                    // Access_denied should be treated as NotConnected.
                    LiveLoginResult result = new LiveLoginResult(LiveConnectSessionStatus.NotConnected, null);
                    this.OnAuthTaskCompleted(result);
                }
                else
                {
                    // We received some other error, then throw it.
                    this.OnAuthTaskCompleted(new LiveLoginResult(error));
                }
            }
            else
            {
                // This is exchange auth code only action, but there is neither code nor error return.
                // The app developer may invoke this at wrong location.
                error = new LiveAuthException(AuthErrorCodes.ClientError, ErrorText.AuthServerResponseNotAvailable);
                this.OnAuthTaskCompleted(new LiveLoginResult(error));
            }

            return taskSource.Task;
        }
 private void OnRefreshTokenCompleted(LiveLoginResult result, Action<LiveLoginResult> completionCallback)
 {
     if (completionCallback != null)
     {
         this.UpdateSession(result);
         completionCallback(result);
     }
     else
     {
         this.OnInitCompleted(result);
     }
 }
 private async void Login(object arg)
 {
     LiveLoginResult = await authClient.LoginAsync(ParseScopeString(this.Scopes));
 }
        private void UpdateSession(LiveLoginResult result)
        {
            Debug.Assert(result != null);

            if (result.Session != null)
            {
                // Set the AuthClient that is needed when refreshing a token.
                result.Session.AuthClient = this.publicAuthClient;

                // We have a new session, update the public property
                this.loginStatus = result;
                this.publicAuthClient.Session = result.Session;

                if (this.refreshTokenHandler != null &&
                    !string.IsNullOrEmpty(result.Session.RefreshToken))
                {
                    RefreshTokenInfo refreshInfo = new RefreshTokenInfo(result.Session.RefreshToken);
                    this.refreshTokenHandler.SaveRefreshTokenAsync(refreshInfo);
                }
            }
            else if (this.loginStatus.Status == LiveConnectSessionStatus.Unknown &&
                result.Status == LiveConnectSessionStatus.NotConnected)
            {
                this.loginStatus = result;
            }
        }
        private void LoadSession(out string authCode, out LiveAuthException error)
        {
            authCode = null;
            error = null;

            // only load session once.
            if (this.loginStatus == null)
            {
                if (this.webContext != null)
                {
                    // Reads current login status from session cookie.
                    this.loginStatus = HttpContextUtility.GetUserLoginStatus(this.webContext);

                    HttpContextUtility.ReadAuthCodeRequest(
                        webContext, out authCode, out this.appRequestState, out this.appRequestTs, out error);
                    if (this.loginStatus.Status == LiveConnectSessionStatus.Unknown &&
                        error != null && error.ErrorCode == AuthErrorCodes.AccessDenied)
                    {
                        this.loginStatus = new LiveLoginResult(LiveConnectSessionStatus.NotConnected, null);
                    }
                }
                else
                {
                    this.loginStatus = new LiveLoginResult(LiveConnectSessionStatus.Unknown, null);
                }

                this.publicAuthClient.Session = this.loginStatus.Session;
            }
        }
        /// <summary>
        /// Parse the response data.
        /// </summary>
        private LiveLoginResult ParseResponseFragment(string fragment)
        {
            Debug.Assert(!string.IsNullOrEmpty(fragment));

            LiveLoginResult loginResult = null;
            IDictionary<string, object> result = LiveAuthClient.ParseQueryString(fragment);
            if (result.ContainsKey(AuthConstants.AccessToken))
            {
                LiveConnectSession sessionData = CreateSession(this, result);

                loginResult = new LiveLoginResult(LiveConnectSessionStatus.Connected, sessionData);
            }
            else if (result.ContainsKey(AuthConstants.Error))
            {
                loginResult = GetErrorResult(result);
            }

            return loginResult;
        }
        private void OnAuthTaskCompleted(
            LiveLoginResult loginResult)
        {
            if (loginResult != null)
            {
                if (loginResult.Session != null)
                {
                    LiveAuthException error = this.ValidateSession(loginResult.Session);
                    if (error != null)
                    {
                        loginResult = new LiveLoginResult(error);
                    }
                    else
                    {
                        // We have a new session, update the LiveAuthClient.Session
                        this.loginStatus = loginResult;

                        if (this.refreshTokenHandler != null &&
                            !string.IsNullOrEmpty(loginResult.Session.RefreshToken))
                        {
                            string userId;
                            if (this.GetUserId(loginResult.Session.AuthenticationToken, out userId, out error))
                            {
                                RefreshTokenInfo refreshInfo = new RefreshTokenInfo(loginResult.Session.RefreshToken, userId);
                                Task saveTokenTask = this.refreshTokenHandler.SaveRefreshTokenAsync(refreshInfo);
                                saveTokenTask.ContinueWith((tk) =>
                                {
                                    this.CompleteAuthTask(loginResult);
                                });
                                return;
                            }
                            else
                            {
                                loginResult = new LiveLoginResult(error);
                            }
                        }
                    }
                }
            }
            else
            {
                // We should return the existing status for cases like already initialized or can't refresh ticket.
                loginResult = this.loginStatus;
            }

            this.CompleteAuthTask(loginResult);
        }
        /// <summary>
        /// Clear the auth state in the current session
        /// </summary>
        public void ClearSession(HttpContextBase context)
        {
            LiveUtility.ValidateNotNullParameter(context, "context");

            HttpContextUtility.ClearUserSession(context);
            this.loginStatus = null;
            this.publicAuthClient.Session = null;
            this.publicAuthClient.FirePendingPropertyChangedEvents();
        }
        private void CompleteAuthTask(LiveLoginResult loginResult)
        {
            Debug.Assert(loginResult != null);

            loginResult = this.ValidateSessionInitScopes(loginResult);            
            HttpContextUtility.UpdateUserSession(this.webContext, loginResult, this.appRequestTs);            

            if (loginResult.Session != null)
            {
                // Only update Session property if there is a new session.
                this.publicAuthClient.Session = loginResult.Session;
            }

            this.publicAuthClient.FirePendingPropertyChangedEvents();

            TaskCompletionSource<LiveLoginResult> taskSource = this.currentTask;
            if (taskSource != null)
            {
                this.currentTask = null;

                if (loginResult.Error != null)
                {
                    var error = loginResult.Error as LiveAuthException;
                    if (error == null)
                    {
                        error = new LiveAuthException(AuthErrorCodes.ClientError, error.Message, loginResult.Error);
                    }

                    error.State = this.appRequestState;
                    taskSource.SetException(loginResult.Error);
                }
                else
                {
                    loginResult.State = this.appRequestState;
                    taskSource.SetResult(loginResult);
                }
            }
        }