Example #1
0
        /// <summary>
        /// Validates the request against XSRF attack.
        /// </summary>
        /// <param name="sessionId">The session id embedded in the query string.</param>
        /// <returns>
        ///   <c>true</c> if the request is safe. Otherwise, <c>false</c>.
        /// </returns>
        private bool ValidateRequestAgainstXsrfAttack(out string sessionId)
        {
            sessionId = null;

            // get the session id query string parameter
            string queryStringSessionId = this.requestContext.Request.QueryString[SessionIdQueryStringName];

            // verify that the query string value is a valid guid
            Guid guid;

            if (!Guid.TryParse(queryStringSessionId, out guid))
            {
                return(false);
            }

            // the cookie value should be the current username secured against this guid
            var cookie = this.requestContext.Request.Cookies[SessionIdCookieName];

            if (cookie == null || string.IsNullOrEmpty(cookie.Value))
            {
                return(false);
            }

            // extract the username embedded within the cookie
            // if there is any error at all (crypto, malformed, etc.), fail gracefully
            string usernameInCookie = null;

            try {
                byte[] encryptedCookieBytes = HttpServerUtility.UrlTokenDecode(cookie.Value);
                byte[] decryptedCookieBytes = MachineKeyUtil.Unprotect(encryptedCookieBytes, AntiXsrfPurposeString, "Token: " + queryStringSessionId);
                usernameInCookie = Encoding.UTF8.GetString(decryptedCookieBytes);
            }
            catch {
                return(false);
            }

            string currentUsername = GetUsername(this.requestContext);
            bool   successful      = string.Equals(currentUsername, usernameInCookie, StringComparison.OrdinalIgnoreCase);

            if (successful)
            {
                // be a good citizen, clean up cookie when the authentication succeeds
                var xsrfCookie = new HttpCookie(SessionIdCookieName, string.Empty)
                {
                    HttpOnly = true,
                    Expires  = DateTime.Now.AddYears(-1)
                };
                this.requestContext.Response.Cookies.Set(xsrfCookie);
            }

            sessionId = queryStringSessionId;
            return(successful);
        }
Example #2
0
        /// <summary>
        /// Requests the specified provider to start the authentication by directing users to an external website
        /// </summary>
        /// <param name="returnUrl">
        /// The return url after user is authenticated.
        /// </param>
        public void RequestAuthentication(string returnUrl)
        {
            // convert returnUrl to an absolute path
            Uri uri;

            if (!string.IsNullOrEmpty(returnUrl))
            {
                uri = UriHelper.ConvertToAbsoluteUri(returnUrl, this.requestContext);
            }
            else
            {
                uri = this.requestContext.Request.GetPublicFacingUrl();
            }

            // attach the provider parameter so that we know which provider initiated
            // the login when user is redirected back to this page
            uri = uri.AttachQueryStringParameter(ProviderQueryStringName, this.authenticationProvider.ProviderName);

            // Guard against XSRF attack by injecting session id into the redirect url and response cookie.
            // Upon returning from the external provider, we'll compare the session id value in the query
            // string and the cookie. If they don't match, we'll reject the request.n
            string sessionId = Guid.NewGuid().ToString("N");

            uri = uri.AttachQueryStringParameter(SessionIdQueryStringName, sessionId);

            // The cookie value will be the current username secured against the session id we just created.
            byte[] encryptedCookieBytes = MachineKeyUtil.Protect(Encoding.UTF8.GetBytes(GetUsername(this.requestContext)), AntiXsrfPurposeString, "Token: " + sessionId);

            var xsrfCookie = new HttpCookie(SessionIdCookieName, HttpServerUtility.UrlTokenEncode(encryptedCookieBytes))
            {
                HttpOnly = true
            };

            if (FormsAuthentication.RequireSSL)
            {
                xsrfCookie.Secure = true;
            }
            this.requestContext.Response.Cookies.Add(xsrfCookie);

            // issue the redirect to the external auth provider
            this.authenticationProvider.RequestAuthentication(this.requestContext, uri);
        }