セッションタイムアウト時のASP.NETプッシュリダイレクト
-
20-08-2019 - |
質問
セッションの有効期限が切れたときにユーザーを自動的に (つまり、ポストバックなしで) プッシュする Web サイトの背後にある技術に関するチュートリアル、ブログエントリ、またはヘルプを探しています。助けていただければ幸いです
解決
通常は、セッションタイムアウトを設定して、あなたはさらに、自動的に正しいセッションタイムアウトの前にセッションをクリアするページに現在のページをリダイレクトするために、ページのヘッダを追加することができます。
http://aspalliance.com/1621_Implementing_a_Session_Timeout_Page_in_ASPNET.2する
からnamespace SessionExpirePage
{
public partial class Secure : System.Web.UI.MasterPage
{
public int SessionLengthMinutes
{
get { return Session.Timeout; }
}
public string SessionExpireDestinationUrl
{
get { return "/SessionExpired.aspx"; }
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
this.PageHead.Controls.Add(new LiteralControl(
String.Format("<meta http-equiv='refresh' content='{0};url={1}'>",
SessionLengthMinutes*60, SessionExpireDestinationUrl)));
}
}
}
SessionExpireDestinationUrlは、セッションや他のユーザーのデータをクリアするページにリンクする必要があります。
リフレッシュヘッダが経過すると、自動的にそのページにリダイレクトされます。
他のヒント
あなたは本当にあなたのウェブサイトからクライアントを「プッシュ」することはできません。あなたのサイトは、クライアントからの要求に応答しますが、それは本当にです。
これが意味することは、あなたが更新され(おそらくサイトのクッキーに、彼らが持っている最新の時間で現在の時刻を比較することで、ユーザーがタイムアウトした際に決定されるクライアント側(Javascriptの)何かを書く必要があるということです差が一定量以上であれば、現在の時刻、ユーザーがサイトのページを訪問するたびに)で、次にリダイレクトします。
(私は、これは単純なケースで動作します。一部の人だけでページ上の一定時間後にユーザを転送するスクリプトを作成提唱されていることに注意して、ユーザーがサイト上で開いている2つのウィンドウがある場合そして、それほど多くではない一つのウィンドウに多く、および他のウィンドウを使用していることは、それほど多くの1が突然ユーザーは常にサイトにされているにもかかわらず、転送ページにユーザーをリダイレクトします。また、そうではありません本当にすべてのセッションと同期して、サーバー側でやっている保つ。一方、それはコードに確かに簡単だし、それは十分だ場合、その後、素晴らしい!)
セクションでは、このようなMETAリフレッシュタグを使用します。
<meta http-equiv="refresh" content="0000; URL=target_page.html">
ここで、0000秒であなたのセッションタイムアウトで、かつにリダイレクトされるページのアドレスをtarget_page.htmlます。
Custom Page クラスと Javascript を使用してもそれを実現できます。
カスタム ページベース クラスを作成し、このクラスに共通の機能コードを書き込みます。このクラスを通じて、他の Web ページと共通の機能を共有できます。このクラスでは、 System.Web.UI.ページ クラス。以下のコードをPagebaseクラスに配置します。
PageBase.cs
namespace AutoRedirect
{
public class PageBase : System.Web.UI.Page
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
AutoRedirect();
}
public void AutoRedirect()
{
int int_MilliSecondsTimeOut = (this.Session.Timeout * 60000);
string str_Script = @"
<script type='text/javascript'>
intervalset = window.setInterval('Redirect()'," +
int_MilliSecondsTimeOut.ToString() + @");
function Redirect()
{
window.location.href='/login.aspx';
}
</script>";
ClientScript.RegisterClientScriptBlock(this.GetType(), "Redirect", str_Script);
}
}
}
その上 オートリダイレクト機能 セッションの有効期限が切れたときに、ログイン ページをリダイレクトするために使用されます。 javascript window.setInterval, この window.setInterval は、JavaScript 関数を特定の時間遅延で繰り返し実行します。ここでは、セッションのタイムアウト値として遅延時間を設定しています。セッションの有効期限に達すると、リダイレクト機能が自動的に実行され、ログイン ページへの転送が制御されます。
OriginalPage.aspx.cs
namespace appStore
{
public partial class OriginalPage: Basepage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
オリジナルページ.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="OriginalPage.aspx.cs" Inherits="AutoRedirect.OriginalPage" %>
Web.config
<system.web>
<sessionState mode="InProc" timeout="3"></sessionState>
</system.web>
注記:Javascript を使用する利点は、location.href の前にアラート ボックスにカスタム メッセージを表示できることです。これはユーザーにとって完全に意味がわかります。Javascriptを使用したくない場合は、メタリダイレクトも選択できます
public void AutoRedirect()
{
this.Header.Controls.Add(new LiteralControl(
String.Format("<meta http-equiv='refresh' content='{0};url={1}'>",
this.Session.Timeout * 60, "login.aspx")));
}
私は初心者としてMVC3 ASp.netを使用しています、私は私のコードでセッション変数を使用しているので、私は(私のセッションの問題を解決するために多くのソリューションを試みたが、私は維持していながら、タイムアウトの後、私はセッションの値を持っていませんでしたそれを使用して、私はちょうど私の問題は、設定ファイルにあったことがわかります。認証とてsessionStateの間にタイムアウトがとても近いはずである。彼らは//テスト用のタイムアウト1と2を追加すると同時に、(空を)殺した..だから、それはだことであるべき少なくとも29と30
私はそれがあまりにも仕事だ、他の方法を使用しました
から始めます:
protected void Session_Start(object src, EventArgs e)
{
if (Context.Session != null)
{
if (Context.Session.IsNewSession)//|| Context.Session.Count==0)
{
string sCookieHeader = Request.Headers["Cookie"];
if ((null != sCookieHeader) && (sCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
{
//if (Request.IsAuthenticated)
FormsAuthentication.SignOut();
Response.Redirect("/Account/LogOn");
}
}
}
}
protected void Session_End(object sender, EventArgs e)
{
//Code that runs when a session ends.
//Note: The Session_End event is raised only when the sessionstate mode
//is set to InProc in the Web.config file. If session mode is set to StateServer
//or SQLServer, the event is not raised.
Session.Clear();
}
と
public class SessionExpireFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext ctx = HttpContext.Current;
// check if session is supported
if (ctx.Session != null)
{
// check if a new session id was generated
if (ctx.Session.IsNewSession)
{
// If it says it is a new session, but an existing cookie exists, then it must
// have timed out
string sessionCookie = ctx.Request.Headers["Cookie"];
if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
{
ctx.Response.Redirect("~/Home/LogOn");
}
}
}
base.OnActionExecuting(filterContext);
}
}
とにもセッションissuseを解決するためのAjaxと協力します:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (Session.Count == 0 || Session["CouncilID"] == null)
Response.Redirect("/Account/LogOn");
if (Request.IsAjaxRequest() && (!Request.IsAuthenticated || User == null))
{
filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
}
else
{
base.OnActionExecuting(filterContext);
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeUserAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!httpContext.Request.IsAjaxRequest())
{//validate http request.
if (!httpContext.Request.IsAuthenticated
|| httpContext.Session["User"] == null)
{
FormsAuthentication.SignOut();
httpContext.Response.Redirect("~/?returnurl=" + httpContext.Request.Url.ToString());
return false;
}
}
return true;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult
{
Data = new
{
// put whatever data you want which will be sent
// to the client
message = "sorry, but you were logged out"
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
ちょうどあなたのWeb.configファイルで、このコードスニペットをコピーして貼り付けます:
<authentication mode="Forms">
<forms loginUrl="~/Login.aspx" slidingExpiration="true" timeout="29" />
</authentication>
<sessionState timeout="30" mode="InProc" cookieless="false" />
あなたのSite.Masterに次の行を置くことができます:
Response.AppendHeader("Refresh",
Convert.ToString((Session.Timeout * 60)) +
";URL=~/Login.aspx");
残念ながら、それは行うことはできません。セッションタイムアウトは、サーバー側でのみ発生し、ユーザーがポストバックアクションのいくつかの種類を実行するまで、あなたはこれを検出しません。
しかし、何を行うことができますと、自動的にあなたのセッションタイムアウトと同じ時間枠内でログアウトページにユーザーをプッシュするいくつかのHTMLやJavaScriptのヘッダコードを注入することです。これは完璧な同期を保証するものではありませんし、あなたのユーザーはいくつかの時間に集中的なアイテムをやっているし、あなたが時計をリセットしていない場合は、問題に遭遇することがあります。
私は一般的に、これを達成するために私をPage_Loadイベントにこのコードを追加します。
' Register Javascript timeout event to redirect to the login page after inactivity
Page.ClientScript.RegisterStartupScript(Me.GetType, "TimeoutScript", _
"setTimeout(""top.location.href = 'Login.aspx'""," & _
ConfigurationManager.AppSettings("SessionTimeoutMilliseconds") & ");", True)
そして、あなたは、次のログオンコントローラを使用する場合、それはログオンする前に要求されたURLにあなたをお送りします。
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
//return Redirect(returnUrl);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
もちろん、あなたは、特定のコントローラクラス、あるいはアクション上[Authorize]
使用する必要があります。
[Authorize]
public class MailController : Controller
{
}
さて、これはZhaphとしてAJAX要求のためにトリッキー取得します - ベンDuguidは指摘しました。ここではAJAXを使用してこの作品を作るために私の解決策だった(TelerikのWebコントロールを使用したが、彼らは、私は信じているASP.NET AJAXツールキットを使用して構築されています)。
一言で言えば、私は自分のスライディング期限切れセッションタイプのものを巻いています。
(AJAX要求がまだPage_Loadイベントをキックオフので、ポストバックまたはAJAX要求)私のSite.Masterで、私はすべてのポストバックのセッション変数を更新しています:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
if (this.Request.IsAuthenticated)
this.pnlSessionKeepAlive.Visible = true;
else
this.pnlSessionKeepAlive.Visible = false;
}
if (this.Session["SessionStartDateTime"] != null)
this.Session["SessionStartDateTime"] = DateTime.Now;
else
this.Session.Add("SessionStartDateTime", DateTime.Now);
}
は、その後、私のsite.masterのための私のマークアップで、私は有効期限をスライド私のカスタムの期限が切れているかどうかをチェックし、確認するために「舞台裏」を使用ASPXページではiframeを含ま
<asp:Panel runat="server" ID="pnlSessionKeepAlive" Visible="false">
<iframe id="frame1" runat="server" src="../SessionExpire.aspx" frameborder="0" width="0" height="0" / >
</asp:Panel>
今私のSessionExpire.aspxページでは、私はしょっちゅうページを更新し、タイムスタンプが経過しているかどうかをチェックし、もしそうなら、私はその後に戻って、ユーザを送信するためにページにログインするかを決定私のlogout.aspxページにリダイレクト:
public partial class SessionExpire : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
/* We have to do all of this because we need to redirect to 2 different login pages. The default .NET
* implementation does not allow us to specify which page to redirect expired sessions, its a fixed value.
*/
if (this.Session["SessionStartDateTime"] != null)
{
DateTime StartTime = new DateTime();
bool IsValid = DateTime.TryParse(this.Session["SessionStartDateTime"].ToString(), out StartTime);
if (IsValid)
{
int MaxSessionTimeout = Convert.ToInt32(ConfigurationManager.AppSettings["SessionKeepAliveMins"]);
IsValid = (DateTime.Now.Subtract(StartTime).TotalMinutes < MaxSessionTimeout);
}
// either their session expired or their sliding session timeout has expired. Now log them out and redirect to the correct
// login page.
if (!IsValid)
this.Logout();
}
else
this.Logout();
// check every 60 seconds to see if the session has expired yet.
Response.AddHeader("Refresh", Convert.ToString(60));
}
private void Logout()
{
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "TimeoutScript",
"setTimeout(\"top.location.href = '../Public/Logout.aspx'\",\"1000\");", true);
}
}
の情報を掲示し、誰上記の人々に感謝し、これは私のソリューションに私をリードし、それが他の人に役立ちます願っています。