シングル サインオンのフォーム認証チケットを共有する単一のドメインに複数のアプリがあります。また、各ページには、セッションの有効期限が切れる 2 分前にユーザーに警告し、ログアウトまたはセッションの延長を許可する JavaScript があります。カウントダウンが 0 になると、自動的にログオフされます。これはすべてうまくいきます。ただし、ユーザーが複数のブラウザー ウィンドウまたはタブを開いてさまざまなアプリを操作すると、惨めに失敗します。ユーザーがウィンドウ B で作業中にウィンドウ A がタイムアウトした場合、ユーザーは次の要求で B からサインアウトされます。
解決策はありますが、実装できないようです。基本的には、ページをレンダリングするときに、チケット発行日のティックを書き出します。次に、自動ログアウトするときに、ハンドラーを ajax 呼び出して、それらのティックが現在のフォーム認証チケットのティックと一致するかどうかを確認します。一致しない場合は、別のアプリがチケットを更新していることがわかるので、ログアウトしません。問題は、slidingexpiration = true を使用しているため、チケットを更新しない汎用ハンドラーを作成できないことです。
function CompareTicket(ticks) {
$.getJSON('http://localhost/MyApp/CompareTicket.ashx?t=' + ticks, function (data) {
if (data == 0)
SessionEnd();
else
SessionExtend();
});
}
以下のハンドラー コードでは、クエリ文字列で送信している値が現在のチケットのティックと一致する場合、データは 0 として返されます。残念ながら、ハンドラーを要求するだけでチケットが更新され、常に新しいティック カウントが返されます。
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
context.Response.ContentEncoding = Encoding.UTF8;
long ticketTicks = ((FormsIdentity)context.User.Identity).Ticket.IssueDate.Ticks;
if (ticketTicks == 0)
context.Response.Write("0");
else
{
long ticks = 0;
if (long.TryParse(context.Request.QueryString["t"], out ticks))
{
if (ticketTicks == ticks)
context.Response.Write("0");
else
context.Response.Write(ticketTicks.ToString());
}
else
context.Response.Write("0");
}
}
チケットを拡張せずにサーバーから JSON リクエストを取得する方法についてのアイデアはありますか?