Exemple #1
0
        /// <summary>
        /// Reads authorization code from current session.
        /// </summary>
        public static bool ReadAuthCodeRequest(
            HttpContextBase webContext,
            out string code,
            out string state,
            out string requestTs,
            out LiveAuthException error)
        {
            Debug.Assert(webContext != null);

            NameValueCollection queryString = webContext.Request.QueryString;

            code = queryString[AuthConstants.Code];
            bool isCodeRequest = !string.IsNullOrEmpty(code);

            string clientState = queryString[AuthConstants.ClientState];
            IDictionary <string, string> states = LiveAuthUtility.DecodeAppRequestStates(clientState);

            state     = states.ContainsKey(AuthConstants.AppState) ? states[AuthConstants.AppState] : null;
            requestTs = states.ContainsKey(AuthConstants.ClientRequestTs) ? states[AuthConstants.ClientRequestTs] : null;

            string errorCode        = queryString[AuthConstants.Error];
            string errorDescription = queryString[AuthConstants.ErrorDescription];

            error = string.IsNullOrEmpty(errorCode) ? null : new LiveAuthException(errorCode, errorDescription, state);

            return(isCodeRequest);
        }
Exemple #2
0
        /// <summary>
        /// An async method to exhange authorization code for auth tokens with the auth server.
        /// </summary>
        public static Task <LiveLoginResult> ExchangeCodeForTokenAsync(string clientId, string clientSecret, string redirectUrl, string authorizationCode)
        {
            Debug.Assert(!string.IsNullOrEmpty(clientId));
            Debug.Assert(!string.IsNullOrEmpty(redirectUrl));
            Debug.Assert(!string.IsNullOrEmpty(authorizationCode));

            string postContent = LiveAuthUtility.BuildCodeTokenExchangePostContent(clientId, clientSecret, redirectUrl, authorizationCode);

            return(RequestAccessTokenAsync(postContent));
        }
Exemple #3
0
        /// <summary>
        /// An async method to get auth tokens using refresh token.
        /// </summary>
        public static Task <LiveLoginResult> RefreshTokenAsync(
            string clientId, string clientSecret, string redirectUrl, string refreshToken,
            IEnumerable <string> scopes)
        {
            Debug.Assert(!string.IsNullOrEmpty(clientId));
            Debug.Assert(!string.IsNullOrEmpty(redirectUrl));
            Debug.Assert(!string.IsNullOrEmpty(refreshToken));

            string postContent = LiveAuthUtility.BuildRefreshTokenPostContent(clientId, clientSecret, redirectUrl, refreshToken, scopes);

            return(RequestAccessTokenAsync(postContent));
        }
        private void ExchangeCodeForToken(string authorizationCode)
        {
            Task <LiveLoginResult> task = LiveAuthRequestUtility.ExchangeCodeForTokenAsync(
                this.clientId,
                null,
                LiveAuthUtility.BuildDesktopRedirectUrl(),
                authorizationCode);

            task.ContinueWith((Task <LiveLoginResult> t) =>
            {
                this.OnExchangeCodeCompleted(t.Result);
            });
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        /// <summary>
        /// Generates a consent URL that includes a set of provided  parameters.
        /// </summary>
        /// <param name="scopes">A list of scope values that the user will need to authorize.</param>
        /// <param name="options">A table of optional authorization parameters to be encoded into the URL.</param>
        /// <returns>The generated login URL value.</returns>
        public string GetLoginUrl(IEnumerable <string> scopes, IDictionary <string, string> options)
        {
            LiveUtility.ValidateNotEmptyStringEnumeratorArguement(scopes, "scopes");

            string      locale      = null;
            string      state       = null;
            DisplayType display     = DisplayType.WinDesktop;
            ThemeType   theme       = ThemeType.Win7;
            string      redirectUrl = LiveAuthUtility.BuildDesktopRedirectUrl();

            if (options != null)
            {
                if (options.ContainsKey(AuthConstants.Locale))
                {
                    locale = options[AuthConstants.Locale];
                }

                if (options.ContainsKey(AuthConstants.ClientState))
                {
                    state = options[AuthConstants.ClientState];
                }

                if (options.ContainsKey(AuthConstants.Display))
                {
                    string displayStr = options[AuthConstants.Display];
                    if (!Enum.TryParse <DisplayType>(displayStr, true, out display))
                    {
                        throw new ArgumentException(ErrorText.ParameterInvalidDisplayValue, "display");
                    }
                }

                if (options.ContainsKey(AuthConstants.Theme))
                {
                    string themeStr = options[AuthConstants.Theme];
                    if (!Enum.TryParse <ThemeType>(themeStr, true, out theme))
                    {
                        throw new ArgumentException(ErrorText.ParameterInvalidDisplayValue, "theme");
                    }
                }
            }

            if (locale == null)
            {
                locale = CultureInfo.CurrentUICulture.ToString();
            }

            return(this.authClient.GetLoginUrl(scopes, redirectUrl, display, theme, locale, state));
        }
        //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);
        }
        /// <summary>
        /// Exchange authentication code for access token.
        /// </summary>
        /// <param name="context">The HttpContextBase instance</param>
        /// <param name="redirectUri">The redirect URL of the app.</param>
        /// <returns>An async Task instance.</returns>
        public Task <LiveLoginResult> ExchangeAuthCodeAsync(
            HttpContextBase context,
            string redirectUrl)
        {
            LiveUtility.ValidateNotNullParameter(context, "context");

            if (string.IsNullOrWhiteSpace(redirectUrl))
            {
                redirectUrl = LiveAuthUtility.GetCurrentRedirectUrl(context.Request.Url);
            }
            else
            {
                LiveUtility.ValidateUrl(redirectUrl, "redirectUrl");
            }

            return(this.authClient.ExchangeAuthCodeAsync(redirectUrl, context));
        }
        /// <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>
        /// <param name="context">The HttpContextBase instance of current request.</param>
        /// <param name="redirectUrl">The redirect URL of the app. This must match exactly the Url that is used to
        /// generate the login Url via LiveAuthClient.GetLoginUrl</param>
        /// <param name="scopes">A list of scopes to validate whether the user has consented. If the available session
        /// does not satisfy the specified scopes, NotConnected status will be returned. However, the developer still
        /// can find the available session throw the Session property.</param>
        /// <returns>An async Task instance</returns>
        public Task <LiveLoginResult> InitializeWebSessionAsync(
            HttpContextBase context,
            string redirectUrl,
            IEnumerable <string> scopes)
        {
            LiveUtility.ValidateNotNullParameter(context, "context");
            if (string.IsNullOrWhiteSpace(redirectUrl))
            {
                redirectUrl = LiveAuthUtility.GetCurrentRedirectUrl(context.Request.Url);
            }
            else
            {
                LiveUtility.ValidateUrl(redirectUrl, "redirectUrl");
            }

            return(this.authClient.InitializeWebSessionAsync(redirectUrl, context, scopes));
        }
 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);
     }
 }
Exemple #11
0
        /// <summary>
        /// Creates a LiveConnectSession object based on the parsed response.
        /// </summary>
        private static LiveConnectSession CreateSession(IDictionary <string, object> result)
        {
            var session = new LiveConnectSession();

            Debug.Assert(result.ContainsKey(AuthConstants.AccessToken));
            if (result.ContainsKey(AuthConstants.AccessToken))
            {
                session.AccessToken = result[AuthConstants.AccessToken] as string;

                if (result.ContainsKey(AuthConstants.AuthenticationToken))
                {
                    session.AuthenticationToken = result[AuthConstants.AuthenticationToken] as string;
                }

                if (result.ContainsKey(AuthConstants.ExpiresIn))
                {
                    if (result[AuthConstants.ExpiresIn] is string)
                    {
                        session.Expires = CalculateExpiration(result[AuthConstants.ExpiresIn] as string);
                    }
                    else
                    {
                        session.Expires = DateTimeOffset.UtcNow.AddSeconds((int)result[AuthConstants.ExpiresIn]);
                    }
                }

                if (result.ContainsKey(AuthConstants.Scope))
                {
                    session.Scopes =
                        LiveAuthUtility.ParseScopeString(result[AuthConstants.Scope] as string);
                }

                if (result.ContainsKey(AuthConstants.RefreshToken))
                {
                    session.RefreshToken = result[AuthConstants.RefreshToken] as string;
                }
            }

            return(session);
        }
Exemple #12
0
        /// <summary>
        /// Reads current user session.
        /// </summary>
        public static LiveLoginResult GetUserLoginStatus(HttpContextBase webContext)
        {
            Debug.Assert(webContext != null);

            HttpCookie               cookie  = webContext.Request.Cookies[AuthCookie];
            LiveConnectSession       session = null;
            LiveConnectSessionStatus status  = LiveConnectSessionStatus.Unknown;

            if (cookie != null && cookie.Values != null)
            {
                string accessToken = cookie[AuthConstants.AccessToken];
                if (!string.IsNullOrEmpty(accessToken))
                {
                    session                     = new LiveConnectSession();
                    session.AccessToken         = UrlDataDecode(accessToken);
                    session.AuthenticationToken = UrlDataDecode(cookie[AuthConstants.AuthenticationToken]);
                    session.RefreshToken        = UrlDataDecode(cookie[AuthConstants.RefreshToken]);
                    session.Scopes              = LiveAuthUtility.ParseScopeString(UrlDataDecode(cookie[AuthConstants.Scope]));
                    session.Expires             = LiveAuthWebUtility.ParseExpiresValue(UrlDataDecode(cookie[AuthConstants.Expires]));
                    status = session.IsValid ? LiveConnectSessionStatus.Connected : LiveConnectSessionStatus.Expired;
                }
                else
                {
                    // If we previously recorded NotConnected, take that value.
                    // Ignore other values that may be set by JS library.
                    LiveConnectSessionStatus statusFromCookie;
                    if (Enum.TryParse <LiveConnectSessionStatus>(cookie[AuthConstants.Status],
                                                                 true /*ignore case*/,
                                                                 out statusFromCookie))
                    {
                        if (statusFromCookie == LiveConnectSessionStatus.NotConnected)
                        {
                            status = statusFromCookie;
                        }
                    }
                }
            }

            return(new LiveLoginResult(status, session));
        }
Exemple #13
0
        /// <summary>
        /// Check if current session has a token request.
        /// </summary>
        public static bool ReadRefreshTokenRequest(
            HttpContextBase webContext,
            out string clientId,
            out IEnumerable <string> scopes)
        {
            clientId = null;
            scopes   = null;
            bool isTokenRequest = false;

            if (webContext != null)
            {
                NameValueCollection queryString = webContext.Request.QueryString;
                string requestToken             = queryString[AuthConstants.ResponseType];
                isTokenRequest = (requestToken == AuthConstants.Token);
                if (isTokenRequest)
                {
                    clientId = queryString[AuthConstants.ClientId];
                    // If this is sent by the client library, the token response should honor the scope parameter.
                    scopes = LiveAuthUtility.ParseScopeString(queryString[AuthConstants.Scope]);
                }
            }

            return(isTokenRequest);
        }
Exemple #14
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);
        }
Exemple #15
0
 /// <summary>
 /// Gets the logout URL.
 /// </summary>
 /// <returns>The logout URL.</returns>
 public string GetLogoutUrl()
 {
     return(LiveAuthUtility.BuildLogoutUrl());
 }
Exemple #16
0
 /// <summary>
 /// Generates a logout URL.
 /// </summary>
 public string GetLogoutUrl(string redirectUrl)
 {
     return(LiveAuthUtility.BuildLogoutUrl(this.clientId, redirectUrl));
 }
Exemple #17
0
 /// <summary>
 /// Generates a consent URL that includes a set of provided  parameters.
 /// </summary>
 public string GetLoginUrl(IEnumerable <string> scopes, string redirectUrl, DisplayType display, string locale, string state)
 {
     return(LiveAuthUtility.BuildAuthorizeUrl(this.clientId, redirectUrl, scopes, ResponseType.Code, display, ThemeType.None, locale, state));
 }