none
настройка sessionState RRS feed

  • Вопрос

  • Добрый день!

    Проблема с sessionState mode="SQLServer". Есть asp.net mvc3 приложение, в котором работать можно только после авторизации, т.е. все действия в контроллерах имеют атрибут [Authorize].  На хостинге база сконфигурированна для использования SessionState.  Конифигурация sessionState задана следующим образом: 

    <sessionState mode="SQLServer"
    allowCustomSqlDatabase="true"
    sqlConnectionString="Data Source=tcp:s05.winhost.com;Initial Catalog=DB_42413_novstylecrm;User ID=DB_42413_novstylecrm_user;Password=*******;Integrated Security=False;"
    cookieless="false"
     timeout="10"/>

    Проблема в том, что приложение почему то не использует эту конфигурацию(видимо продолжет действовать дефолтная InProc) и после recycle application pool сбрасываются сессия и авторизация и пользователь перенаправляется на страницу логина.  Также если, например, сделать ошибку в параметре sqlConnectionString допустим в пароле, то приложение должно выбросить исключение, но этого не происходит. 

    Кто знгает подскажите, пожалуйста, в чем проблема. Заранее спасибо!

    6 июня 2012 г. 12:00

Ответы

  • Сессия (session state) не имеет ничего общего с авторизацией и логином.

    Логин, при использовании forms auth, завязан на cookies. cookie, отвечающий за логин, подписывается ключами, указанными в конфиге, в секции machineKey. 

    По умолчанию там задано autogenerate, isolateapps. Т.е. ключи генерирует сам asp.net, разные для разных приложений на сервере. Проблема в том, что в IIS 7 ключи генерируются заново при рестарте приложения. И старые cookies логина становятся невалидными. Единственный способ сделать cookies валидными надолго - это сгенерировать ключи, и вписать из в web.config. Вот онлайновый генератор: http://aspnetresources.com/tools/machineKey.

    • Помечено в качестве ответа Ryfin 7 июня 2012 г. 18:18
    7 июня 2012 г. 11:33
  • PashaPash абсолютно прав. Я не разобравшись до конца начал задавать вопросы.

    Проблема с авторизацией оказалась в том что использовались Persistent куки , которые привязаны к сессии. В режиме InProc id сессии хранится на сервере в процессе, и когда процесс перезапускается, то кука становится не действительной. Проблема решалась использованием куки с таймаутом и добавлением  конфигурации machineKey. Может я и ошибаюсь, но эти действия помогли.

    Проблему с хранением сессии в бд пока не удалось решить.



    • Изменено Ryfin 7 июня 2012 г. 18:29
    • Помечено в качестве ответа Abolmasov DmitryModerator 8 июня 2012 г. 11:35
    7 июня 2012 г. 18:28
  • >> Проблема с авторизацией оказалась в том что использовались Persistent куки , которые привязаны к сессии.

    Persistent куки не привязаны к сессии. Persistent переживают рестарт браузера. при не-Persistent. Persistent - это аналог галочки "remember me" на сайтах.

    Если она установлена - то пользователь будет залогинен вечно (точнее столько, сколько задано в секции forms в конфиге, 1 месяц по умолчанию в свежесозданных проектах), даже если перезапустит браузер.

    Если она не установлена - то пользователь будет залогинен пока не закроет браузер. После закрытия/открытия браузер сотрет куку, и при следующем заходе у пользователя опять спросит имя и пароль).

    Должно было хватить вписывания ключей. InProc и сессия вообще тут никакой роли не сыграли.

    >> Проблему с хранением сессии в бд пока не удалось решить.

    Так а в чем, собственно, проблема с сессией в БД (если учесть, что вылогинивание при рестарте было вызвано отсутствием ключей в конфиге, а не сессией).

    7 июня 2012 г. 19:42

Все ответы

  • Странно, пока ещё не сталкивался с подобным, у меня все MVC 3 приложения нормально работали с сессией в базе. А это у Вас происходит на локальной машине, или на сервере и если можно файл web.config приложения?
    • Помечено в качестве ответа Ryfin 7 июня 2012 г. 18:18
    • Снята пометка об ответе Ryfin 7 июня 2012 г. 18:18
    6 июня 2012 г. 17:01
    Модератор
  • Сессия (session state) не имеет ничего общего с авторизацией и логином.

    Логин, при использовании forms auth, завязан на cookies. cookie, отвечающий за логин, подписывается ключами, указанными в конфиге, в секции machineKey. 

    По умолчанию там задано autogenerate, isolateapps. Т.е. ключи генерирует сам asp.net, разные для разных приложений на сервере. Проблема в том, что в IIS 7 ключи генерируются заново при рестарте приложения. И старые cookies логина становятся невалидными. Единственный способ сделать cookies валидными надолго - это сгенерировать ключи, и вписать из в web.config. Вот онлайновый генератор: http://aspnetresources.com/tools/machineKey.

    • Помечено в качестве ответа Ryfin 7 июня 2012 г. 18:18
    7 июня 2012 г. 11:33
  • Да, но странно именно то, что при преднамеренной ошибке sqlConnectionString исключение не выбрасывается.
    7 июня 2012 г. 13:46
    Модератор
  • Выбрасывается. Возможно, кусок, на котором тестируете, не требует сессии. Или  mode="SQLServer" не прописан. 

    В любом случае, session state и его настройки не имеют ничего общего с аутентификацией и авторизацией. 

    В MVC Session используется только для хранения TempData. Пока TempData не используется - сессия не нужна.


    • Изменено PashaPash 7 июня 2012 г. 15:44
    7 июня 2012 г. 15:39
  • А Вы попытайтесь использовать сессию явно (добавьте что нибудь в объект Session в контроллере), то есть чтобы знать точно, что она используется и посмотрите выбрасывается ли тогда исключение, когда пароль неверный. А то как уже сказал PashaPash возможно она не используется и поэтому ошибки и нет. А она скорее всего работает нормально.
    7 июня 2012 г. 15:50
    Модератор
  • >> Проблема в том, что приложение почему то не использует эту конфигурацию(видимо продолжет действовать дефолтная InProc) и после recycle application pool сбрасываются сессия и авторизация и пользователь перенаправляется на страницу логина. 

    Проблема в отсутствующих ключах в конфиге. Не в сессии. Я же написал про это выше, уже 2 раза.

    >> А Вы попытайтесь использовать сессию явно (добавьте что нибудь в объект Session в контроллере), то есть чтобы знать точно, что она используется и посмотрите выбрасывается ли тогда исключение, когда пароль неверный.

    TempData["aaa"] = "bbb"; в контроллере валит приложение с вполне ожидаемым SqlException. Без него - работает. ASP.NET не создает сессию до первого обращения (точнее, не сохраняет ее, если она пустая).

    7 июня 2012 г. 15:56
  • PashaPash абсолютно прав. Я не разобравшись до конца начал задавать вопросы.

    Проблема с авторизацией оказалась в том что использовались Persistent куки , которые привязаны к сессии. В режиме InProc id сессии хранится на сервере в процессе, и когда процесс перезапускается, то кука становится не действительной. Проблема решалась использованием куки с таймаутом и добавлением  конфигурации machineKey. Может я и ошибаюсь, но эти действия помогли.

    Проблему с хранением сессии в бд пока не удалось решить.



    • Изменено Ryfin 7 июня 2012 г. 18:29
    • Помечено в качестве ответа Abolmasov DmitryModerator 8 июня 2012 г. 11:35
    7 июня 2012 г. 18:28
  • "Проблему с хранением сессии в бд пока не удалось решить." - а что именно не получается?
    7 июня 2012 г. 18:31
    Модератор
  • На сколько я понимаю, при запуске приложения должна добавляться запись с сессией в таблице ASPStateTempSessions, но записи в нее не добавляются.
    7 июня 2012 г. 18:37
  • Как я уже сказал, Вы должны использовать сессию, иначе никакие данные не запишутся. При создании БД для хранения сессии со следующим ключём

    aspnet_regsql.exe -S localhost -E -ssadd 
    

    таблицы сессии хранятся в базе tempdb, очищаются после таймаута или перезапуска SQL Server.

    А при создании базы так

    aspnet_regsql.exe -S localhost -Е -ssadd -sstype p 
    данные хранятся там постоянно, тогда реально, что либо в них увидеть.

    7 июня 2012 г. 18:54
    Модератор
  • >> Проблема с авторизацией оказалась в том что использовались Persistent куки , которые привязаны к сессии.

    Persistent куки не привязаны к сессии. Persistent переживают рестарт браузера. при не-Persistent. Persistent - это аналог галочки "remember me" на сайтах.

    Если она установлена - то пользователь будет залогинен вечно (точнее столько, сколько задано в секции forms в конфиге, 1 месяц по умолчанию в свежесозданных проектах), даже если перезапустит браузер.

    Если она не установлена - то пользователь будет залогинен пока не закроет браузер. После закрытия/открытия браузер сотрет куку, и при следующем заходе у пользователя опять спросит имя и пароль).

    Должно было хватить вписывания ключей. InProc и сессия вообще тут никакой роли не сыграли.

    >> Проблему с хранением сессии в бд пока не удалось решить.

    Так а в чем, собственно, проблема с сессией в БД (если учесть, что вылогинивание при рестарте было вызвано отсутствием ключей в конфиге, а не сессией).

    7 июня 2012 г. 19:42
  • Записи добавляются только если вы действительно что-то записали в сессию. Запись в сессию это код вида:

    Session[key] = value;

    или в MVC:

    TempData[key] = value;

    ASP.NET обращается к SQL (или к другим хранилищаи сессии) только в двух случаях:

    1. Нужно записать в хранилище непустые данные сессии.

    2. Нужно прочитать их хранилища данные сессии пользователя, для которого они раньше были в хранилице записаны.

    Если вы с сессией не работаете - не добавляете в нее значения - то обращений к SQL нет, и падать нечему. Авторизация и прочее - это не работа с сессией.

    7 июня 2012 г. 19:47