web-dev-qa-db-ja.com

ASP.NET:リクエスト間のSession.SessionIDの変更

ASP.NETページのSession-objectのプロパティSessionIDがリクエスト間で変更されるのはなぜですか?

このようなページがあります:

...
<div>
    SessionID: <%= SessionID %>
</div>
...

また、F5キーを押すたびに、ブラウザーに関係なく出力が変化し続けます。

131
Seb Nilsson

これがまさにその理由だ

Cookieベースのセッション状態を使用する場合、ASP.NETはSessionオブジェクトが使用されるまでセッションデータ用のストレージを割り当てません。その結果、セッションオブジェクトにアクセスするまで、ページリクエストごとに新しいセッションIDが生成されます。アプリケーションがセッション全体で静的セッションIDを必要とする場合、アプリケーションのGlobal.asaxファイルにSession_Startメソッドを実装し、セッションオブジェクトにデータを保存してセッションIDを修正するか、または別の部分でコードを使用できますSessionオブジェクトにデータを明示的に保存するアプリケーション。

http://msdn.Microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx

基本的に、バックエンドでセッションオブジェクトにアクセスしない限り、リクエストごとに新しいsessionIdが生成されます

編集

このコードは、ファイルGlobal.asaxに追加する必要があります。 Sessionオブジェクトにエントリを追加し、セッションが期限切れになるまで修正します。

protected void Session_Start(Object sender, EventArgs e) 
{
    Session["init"] = 0;
}
205
Claudio Redi

Cladudioが示すようにSessionオブジェクトが初期化された場合でも、これが発生する可能性のあるもう1つの、より陰湿な理由があります。

Web.configで、<httpCookies>に設定されているrequireSSL="true"エントリがあり、実際にHTTPSを使用していない場合:特定の要求に対して、セッションCookieは送信されません(または返されない場合があります) 、どちらかはわかりません)つまり、リクエストごとに新しいセッションが行われることになります。

これが難しい方法であることがわかりました。ソース管理でのいくつかのコミット間を数時間かけて行き来し、特定の変更によってアプリケーションが壊れたことがわかりました。

85
Neville Cook

私の場合、セッションCookieにはwww.プレフィックスを含むdomainがあり、www.のないページをリクエストしていることがわかりました。
www.をURLに追加すると、すぐに問題が修正されました。後でCookieドメインを.mysite.comではなくwww.mysite.comに設定するように変更しました。

5
Kniganapolke

Nevilleの答えを使用して(web.configでrequireSSL = trueを削除)and Joel Ethertonのコードをわずかに変更し、SSLモードと非SSLモードの両方で実行されるサイトを処理するコードを以下に示します。ユーザーとページ(私はコードに戻っており、まだSSLでテストしていませんが、動作するはずです-これに戻るには忙しすぎるので、ここにあります:

if (HttpContext.Current.Response.Cookies.Count > 0)
        {
            foreach (string s in HttpContext.Current.Response.Cookies.AllKeys)
            {
                if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid")
                {
                    HttpContext.Current.Response.Cookies[s].Secure = HttpContext.Current.Request.IsSecureConnection;
                }
            }
        }
4
Reid

私の問題は、web.configでこのセットがあったことです

<httpCookies httpOnlyCookies="true" requireSSL="true" />

これは、非SSLでデバッグする場合(デフォルト)、認証Cookieがサーバーに返送されないことを意味します。これは、サーバーがクライアントへのすべての要求に対して新しい認証Cookie(新しいセッションで)を送信することを意味します。

修正するには、web.configでrequiresslをfalseに設定し、web.release.configでtrueに設定するか、デバッグ中にSSLをオンにします。

turn on SSL

3
josh

Session_OnStartが定義されている場合やSessionが初期化されている場合でも、リクエスト間でSessionIDが変わる別の可能性は、URLホスト名に無効な文字(アンダースコアなど)が含まれていることです。これはIE固有(検証されていない)ですが、URLがたとえばhttp://server_name/appである場合、IEはすべてのCookieをブロックし、セッション情報はリクエスト間でアクセス可能。

実際、各リクエストはサーバー上で個別のセッションを起動するため、ページに複数の画像、スクリプトタグなどが含まれている場合、これらのGETリクエストのそれぞれはサーバー上で異なるセッションになります。

詳細: http://support.Microsoft.com/kb/316112

2

私の問題はMicrosoft MediaRoom IPTVアプリケーションにありました。 MPF MRMLアプリケーションはCookieをサポートしていません。 web.configでcookielessセッションを使用するように変更すると、問題が解決しました

<sessionState cookieless="true"  />

これに関する本当に古い記事は次のとおりです。 Cookieless ASP.NET

1
denvercoder9

私の場合、これは開発環境とテスト環境で頻繁に発生していました。上記のすべての解決策を試みたが成功しなかった後、すべてのセッションCookieを削除することでこの問題を解決できることがわかりました。 Web開発者拡張機能により、これが非常に簡単になります。私は主にFirefoxをテストと開発に使用していますが、これはChromeでのテスト中にも発生しました。この修正はChromeでも機能しました。

私はまだ実稼働環境でこれを行う必要がなく、ログインできないという報告を受け取っていません。これは、セッションCookieをセキュリティで保護した後にのみ発生するようです。彼らが安全ではなかったとき、それは過去に決して起こりませんでした。

1
Matt L

私の場合は、外部アプリケーションのゲートウェイからリダイレクトした後にセッションを変更していたためですさまざまなセッションのウェブサイト。

要約すれば

IISの代わりにIISでホストされているアプリケーションをデバッグし、マシンを高速化および混合する場合は、より注意を払ってください http:// Ip および http :// localhost さまざまなページ

1
Iman Abidi

セッションタイムアウトが非常に短くないことを確認し、Cookieベースのセッションを使用している場合は、セッションを受け入れていることも確認してください。

FireFox webDeveloperToolbarは、アプリケーションに設定されたCookieを確認できるため、このような場合に役立ちます。

0
Mitchel Sellers

私は.NET Core 2.1を使用していますが、この質問はCoreに関するものではないことをよく知っています。しかし、インターネットは不足しており、Googleが私をここに連れてきたので、誰かを数時間救うことを望んでいました。


Startup.cs

services.AddCors(o => o.AddPolicy("AllowAll", builder =>
            {
                builder
                    .WithOrigins("http://localhost:3000")     // important
                    .AllowCredentials()                       // important
                    .AllowAnyMethod()
                    .AllowAnyHeader();       // obviously just for testing
            }));

client.js

const resp = await fetch("https://localhost:5001/api/user", {
            method: 'POST',
            credentials: 'include',                           // important
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        })

Controllers/LoginController.cs

namespace WebServer.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        [HttpPost]
        public IEnumerable<string> Post([FromBody]LoginForm lf)
        {
            string prevUsername = HttpContext.Session.GetString("username");
            Console.WriteLine("Previous username: " + prevUsername);

            HttpContext.Session.SetString("username", lf.username);

            return new string[] { lf.username, lf.password };
        }
    }
}

セッションの書き込みと読み取りは機能しますが、ブラウザにCookieが渡されていないようです。少なくとも「Set-Cookie」ヘッダーがどこにも見つかりませんでした。

0
krivar

セッションIDのリセットには多くの原因があります。ただし、上記のいずれも私の問題とは関係ありません。したがって、今後の参考のために説明します。

私の場合、各リクエストで新しいセッションが作成されると、無限リダイレクトループが発生しました。リダイレクトアクションはOnActionExecutingイベントで発生します。

また、クライアント側でサイトをキャッシュしないようにするために、すべてのhttpヘッダーをクリアしました(OnActionExecutingイベントをResponse.ClearHeadersメソッドを使用して)。しかし、その方法は、ユーザーのセッションに関する情報を含むすべてのヘッダーをクリアし、その結果、一時ストレージ内のすべてのデータをクリアします(後でプログラムで使用していました)。そのため、Session_Startイベントで新しいセッションを設定しても解決しませんでした。

問題を解決するために、リダイレクトが発生したときにヘッダーを削除しないようにしました。

それが誰かを助けることを願っています。

0
user3253726

私はこの問題に別の方法で遭遇しました。この属性[SessionState(SessionStateBehavior.ReadOnly)]を持っているコントローラーは、アプリの起動時に元のセッションで値を設定したにもかかわらず、別のセッションから読み取っていました。私は_layout.cshtmlを介してセッション値を追加していました(おそらく最良のアイデアではないでしょうか?)

属性を削除すると、元のセッション(およびSessionId)がそのまま残るため、明らかに問題が発生するのは読み取り専用でした。 Claudio's/Microsoftのソリューションを使用して修正しました。

0
goku_da_master