Сервер не может изменить файлы cookie после отправки заголовков HTTP, как это исправить? - PullRequest
9 голосов
/ 27 ноября 2011

Я хочу автоматически войти в систему моих пользователей на page_load главной страницы, если имя пользователя и пароль существуют в файлах cookie!
поэтому я написал код ниже:

        protected void Page_Load(object sender, EventArgs e)
        {
            LoadDataFromCookieIfExistAndLogin();
        }

private void LoadDataFromCookieIfExistAndLogin()
{
    string Query = Request.Url.Query.ToString();
    string[] Ar_Query = new string[2];
    string[] splitter = { "%2f" };
    Ar_Query = Query.Split(splitter, System.StringSplitOptions.None);
    string[] Ar_new_Query = new string[2];
    int minLength = Math.Min(Ar_Query.Length, Ar_new_Query.Length);
    Array.Copy(Ar_Query, Ar_new_Query, minLength);
    if (string.IsNullOrEmpty(Ar_new_Query[1]))
    {
        Ar_new_Query[1] = string.Empty;
    }

    if ((Request.QueryString["ReturnURL"] != null) && (Ar_new_Query[1].ToString().ToUpper() == "ADMIN"))
    {
        Session.Clear();
        FormsAuthentication.SignOut();
    }
    else if ((Request.QueryString["ReturnURL"] != null) && (Ar_new_Query[1].ToString().ToUpper() == "ELMAH.AXD"))
    {
        Session.Clear();
        FormsAuthentication.SignOut();
    }
    else
    {
        HttpCookie Situation_Cookie = Request.Cookies["Situation"];
        if (Situation_Cookie != null)
        {
            if (Situation_Cookie["Login"] == "Yes")
            {
                HttpCookie Data_Cookie = Request.Cookies["Data"];
                if (Data_Cookie != null)
                {
                    string UserName = Data_Cookie["UserName"].ToString();
                    string PassWord = ata_Cookie["PassWord"].ToString();

                    string HashedPass = FormsAuthentication.HashPasswordForStoringInConfigFile(PassWord, "MD5");
                    DataSet dsUsers = DataLayer.Users.SelectRowForLogin_FromCookie(UserName, HashedPass);
                    if (dsUsers.Tables["Users"].Rows.Count > 0)
                    {
                        DataRow drUsers = dsUsers.Tables["Users"].Rows[0];

                        if (Session["User_ID"] == null)
                        {
                            Session["UserName"] = UserName;
                            Session["Password"] = PassWord;
                            Session["User_ID"] = drUsers["ID"].ToString();
                            Session["UserType_ID"] = drUsers["UserType_ID"].ToString();
                            DataLayer.OnlineUsers.UpdateRow_UserID_By_SessionID(
                                                                                 Session["User_ID"],
                                                                                 Session.SessionID);
                        }
                        if (!HttpContext.Current.User.Identity.IsAuthenticated)
                        {
                            FormsAuthentication.SetAuthCookie(drUsers["ID"].ToString(), true);
                        }
                    }
                }
            }
        }
    }
}

также для понимания моих кодов входа я использую RoleProvider Как показано ниже:

  using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Data;

    namespace NiceFileExplorer.Classes
    {
        public class NiceFileExplorerRoleProvider : RoleProvider
        {
            public override void AddUsersToRoles(string[] usernames, string[] roleNames)
            {
                throw new NotImplementedException();
            }

            public override string ApplicationName
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }

            public override void CreateRole(string roleName)
            {
                throw new NotImplementedException();
            }

            public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
            {
                throw new NotImplementedException();
            }

            public override string[] FindUsersInRole(string roleName, string usernameToMatch)
            {
                throw new NotImplementedException();
            }

            public override string[] GetAllRoles()
            {
                throw new NotImplementedException();
            }

            //public override string[] GetRolesForUser(string username)
            public override string[] GetRolesForUser(string User_ID)
            {
                string[] UserTypes = new string[1];
                DataSet dsUser = DataLayer.Users.SelectRowWithUserTypeInfo(int.Parse(User_ID));
                if (dsUser.Tables["Users"].Rows.Count > 0)
                {
                    DataRow drUser = dsUser.Tables["Users"].Rows[0];
                    UserTypes[0] = drUser["Name"].ToString();
                }
                if (User_ID == "-255")
                {
                    UserTypes[0] = "Administrators";
                }
                return UserTypes;
            }

            public override string[] GetUsersInRole(string roleName)
            {
                throw new NotImplementedException();
            }

            public override bool IsUserInRole(string username, string roleName)
            {
                throw new NotImplementedException();
            }

            public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
            {
                throw new NotImplementedException();
            }

            public override bool RoleExists(string roleName)
            {
                throw new NotImplementedException();
            }
        }

}

иногда у меня есть ошибка ниже:

System.Web.HttpException: сервер не может изменять файлы cookie после отправки заголовков HTTP.

System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Web.HttpException (0x80004005): Server cannot modify cookies after HTTP headers have been sent.
   at System.Web.HttpCookieCollection.Add(HttpCookie cookie)
   at System.Web.Security.FormsAuthentication.SetAuthCookie(String userName, Boolean createPersistentCookie, String strCookiePath)
   at NiceFileExplorer.en.Site1.Page_Load(Object sender, EventArgs e)
   at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.HandleError(Exception e)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

похоже, проблема в следующей строке:

FormsAuthentication.SetAuthCookie (drUsers ["ID"]. ToString (), true);

что означает эта ошибка и как я могу ее предотвратить?

Ответы [ 3 ]

11 голосов
/ 27 ноября 2011

"System.Web.HttpException: сервер не может изменять файлы cookie после отправки заголовков HTTP."

Эта ошибка означает, что вы пытаетесь изменить файлы cookie после завершения ответа http.

Я думаю, что проблема в том, что вы пытаетесь изменить куки после выполнения FormsAuthentication.SignOut ().

Как и в MSDN, это происходит при вызове метода SignOut ()

Когда вызывается метод SignOut, перенаправление на страницу входа приложения выполняется путем вызова метода Redirect с параметром endResponse, установленным в false. Перенаправление не происходит до тех пор, пока не завершится выполнение текущей страницы, поэтому можно запустить дополнительный код. Если код не содержит явного перенаправления на другую страницу, пользователь перенаправляется на страницу входа, настроенную в файле конфигурации приложения.

Итак, вы пытаетесь изменить файлы cookie после перенаправления. Вы можете избежать этой ошибки, установив значение cookie перед перенаправлением.

3 голосов
/ 27 ноября 2011

Если вы используете стандартную проверку подлинности формы ASP.Net, эта функция доступна для проверки подлинности формы, если вы используете постоянные файлы cookie. См. Статью MSDN здесь . Проверьте раздел «Создание файла cookie проверки подлинности с помощью форм» документа.

Вам не нужно сохранять комбинацию имени пользователя и пароля в cookie. Это не очень хорошая практика, так как любой может узнать это имя пользователя \ пароль из cookie. Я настоятельно рекомендую вам прочитать приведенную выше статью, чтобы понять, как работает проверка подлинности формы.

0 голосов
/ 26 августа 2014

для быстрого тестирования Я очистил историю браузера и прекрасно работает на моем конце ..

...