public static byte[] EncodeCookie(Auth0Token token)
        {
            var bytes = token.ToBytes();

            for (int i = 0; i < DefaultCookieTransforms.Length; ++i)
            {
                bytes = DefaultCookieTransforms[i].Encode(bytes);
            }
            return(bytes);
        }
        public static void WriteSessionCookie(HttpApplication application, Auth0Token token)
        {
            var request  = application.Context.Request;
            var response = application.Context.Response;

            var bytes      = EncodeCookie(token);
            var cookie     = Convert.ToBase64String(bytes);
            var chunkCount = cookie.Length / CookieChunkSize + (cookie.Length % CookieChunkSize == 0 ? 0 : 1);

            for (int i = 0; i < chunkCount; ++i)
            {
                var setCookie = new StringBuilder();
                setCookie.Append(LiveAuth);
                if (i > 0)
                {
                    setCookie.Append(i.ToString(CultureInfo.InvariantCulture));
                }

                setCookie.Append('=');

                int startIndex = i * CookieChunkSize;
                setCookie.Append(cookie.Substring(startIndex, Math.Min(CookieChunkSize, cookie.Length - startIndex)));
                setCookie.Append("; path=/");
                if (request.Url.Scheme == "https")
                {
                    setCookie.Append("; secure");
                }
                setCookie.Append("; HttpOnly");
                response.Headers.Add("Set-Cookie", setCookie.ToString());
            }

            var cookies = request.Cookies;
            var index   = chunkCount;

            while (true)
            {
                var cookieName = LiveAuth;
                if (index > 0)
                {
                    cookieName += index.ToString(CultureInfo.InvariantCulture);
                }

                if (cookies[cookieName] == null)
                {
                    break;
                }

                // remove old cookie
                response.Headers.Add("Set-Cookie", String.Format(DeleteCookieFormat, cookieName));
                ++index;
            }
        }
        public static Auth0Token DecodeCookie(byte[] bytes)
        {
            try
            {
                for (int i = DefaultCookieTransforms.Length - 1; i >= 0; --i)
                {
                    bytes = DefaultCookieTransforms[i].Decode(bytes);
                }
                return(Auth0Token.FromBytes(bytes));
            }
            catch (Exception ex)
            {
                Auth0Trace.WriteLine("DecodeCookie failed with {0}", ex);

                // bad cookie
                return(null);
            }
        }
        public static Auth0Token AuthenticateUser(HttpApplication application, out string redirectUri)
        {
            redirectUri = null;

            var request    = application.Context.Request;
            var requestUrl = new Uri(request.Url, request.RawUrl);

            if (!requestUrl.AbsolutePath.Equals(LoginCallbackPath, StringComparison.OrdinalIgnoreCase))
            {
                return(ReadSessionCookie(application));
            }

            var query = HttpUtility.ParseQueryString(requestUrl.Query);
            var code  = query["code"];

            if (String.IsNullOrEmpty(code))
            {
                return(ReadSessionCookie(application));
            }

            var tokenRequestUri = String.Format("https://{0}/oauth/token", Auth0Domain);
            var client_id       = Auth0ClientId;
            var client_secret   = Auth0ClientSecret;
            var redirect_uri    = GetRedirectUrl(application);

            var payload = new StringBuilder("grant_type=authorization_code");

            payload.AppendFormat("&client_id={0}", WebUtility.UrlEncode(client_id));
            payload.AppendFormat("&client_secret={0}", WebUtility.UrlEncode(client_secret));
            payload.AppendFormat("&redirect_uri={0}", WebUtility.UrlEncode(redirect_uri));
            payload.AppendFormat("&code={0}", WebUtility.UrlEncode(code));

            var webRequest = (HttpWebRequest)WebRequest.Create(tokenRequestUri);

            webRequest.Method      = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            using (var stream = webRequest.GetRequestStream())
            {
                var bytes = Encoding.UTF8.GetBytes(payload.ToString());
                stream.Write(bytes, 0, bytes.Length);
            }

            try
            {
                var webResponse = (HttpWebResponse)webRequest.GetResponse();
                using (var stream = webResponse.GetResponseStream())
                {
                    var token = Auth0Token.FromStream(stream);

                    WriteSessionCookie(application, token);

                    redirectUri = query["state"];

                    return(token);
                }
            }
            catch (WebException ex)
            {
                Auth0Trace.WriteLine("POST {0} failed with {1}", tokenRequestUri, ex);

                throw HandleOAuthError(ex, tokenRequestUri);
            }
        }