6

1 つのユーザー名の同時ログインを防止する機能を作成し、次のようにアクションで呼び出します。

        int userId = (int)WebSecurity.CurrentUserId;

        if ((this.Session.SessionID != dba.getSessionId(userId)) || dba.getSessionId(userId) == null)
        {
            WebSecurity.Logout();
            return RedirectToAction("Index", "Home");
        }

ポイントは、ユーザーがログインするたびに、セッションIDをデータベースフィールドに保存することです。したがって、同じユーザー名ですでにログインしているユーザーに同じユーザー名でログインすると、そのデータベース フィールドがこの新しいセッションで上書きされます。DB の sessionID がログインしているユーザーの現在のセッション ID と同じでない場合、そのユーザーはログアウトされます。

コードのこの部分を 1 か所に配置する可能性はありますか、それともアプリケーションのすべてのアクションに配置する必要がありますか?

Global.asaxで試しました:

void Application_BeginRequest(object sender, EventArgs e)
    {
        if (Session["ID"] != null)
        {
            int userId = Convert.ToInt32(Session["ID"]);
            if ((this.Session.SessionID != db.getSessionId(userId)) || db.getSessionId(userId) == null)
            {
                WebSecurity.Logout();
            }
        }
    }

しかし、次のようにしようとすると、ここで Session も WebSecurity クラスも使用できません。

    void Application_BeginRequest(object sender, EventArgs e)
    {
        int userId = (int)WebSecurity.CurrentUserId;

        if ((this.Session.SessionID != db.getSessionId(userId)) || db.getSessionId(userId) == null)
        {
            WebSecurity.Logout();
            Response.RedirectToRoute("Default");                
        }
    }

null参照例外が発生するためです。

編集

私はこれを使用しました:

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        int userId = (int)WebSecurity.CurrentUserId;
        using (var db = new UsersContext())
        {
            string s = db.getSessionId(userId);

            if ((filterContext.HttpContext.Session.SessionID != db.getSessionId(userId)) || db.getSessionId(userId) == null)
            {
                WebSecurity.Logout();
                filterContext.Result = new RedirectResult("/Home/Index");
            }
        }
    }

コンテキストに using ステートメントを使用する必要がありました。そうしないと、db.getSessionId(userId)が古い sessionId を返していました。メソッドは次のとおりです。

    public string getSessionId(int userId)
    {
        string s = "";
        var get = this.UserProfiles.Single(x => x.UserId == userId);
        s = get.SessionId;
        return s;
    }

非常に奇妙です。なぜそれが起こったのかを読む必要があります。

1 つのことを除いて、すべて正常に動作します。Jsonを返すコントローラーにJsonResultアクションが1つありますが、イベント(enterイベントのテキストボックス)がPOSTをトリガーできないため(前にログアウトしたためだと思います)、リダイレクトは機能しません。そのJsonアクションに投稿して、コールバックとリダイレクトを受け取ることさえできません。それに関する手がかりはありますか?

                        success: function (data) {
                        if (data.messageSaved) {
                            //data received - OK!
                        }
                        else {
                            // in case data was not received, something went wrong redirect out
                            window.location.href = urlhome;
                        }
                    }

ActionFilterAttribute を使用する前に、コードを使用して POST 内のさまざまなセッションをチェックしました。もちろん、コールバックを作成できるため、データを受信しなかった場合はリダイレクトできます。リダイレクトしません:)

4

6 に答える 6

2

というアクション フィルターを作成し、SeatCheck各コントローラーを次のように装飾します。

[SeatCheck]
public class NoteController : BaseController
{

私たちはそれを使って座席数やその他の機能を取得していますが、それを使用すると、何も考えずにあらゆる場所を簡単に制御できます。

proejctActionFiltersフォルダーには、SeatCheck.cs次のようなファイルがあります。

namespace site.ActionFilters
{
  public class SeatCheckAttribute : ActionFilterAttribute
  {
     public override void OnActionExecuting(ActionExecutingContext filterContext)
     {

このようにアクションフィルターでSessionIDを取得できます

 filterContext.HttpContext.Session.SessionID
于 2013-08-08T22:46:54.660 に答える
1

はい、確かにあります。から派生した属性を使用できますActionFilterAttribute

というクラスを書きますSessionSecurityAttribute

public class SessionSecurityAttribute : ActionFilterAttribute
{
    public MyDbConn MyDbConn { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var session = filterContext.RequestContext.HttpContext.Session;
        if (session["ID"] != null && WebSecurity.IsAuthenticated)
        {
            int userId = Convert.ToInt32(session["ID"]);
            if ((sessionID != MyDbConn.getSessionId(userId)) || MyDbConn.getSessionId(userId) == null)
            {
                WebSecurity.Logout();
            }
        }
    }
}

疑問が残ります: データベースへのアクセスを許可しながら、これらの属性をアクションに追加するにはどうすればよいでしょうか? それは簡単です:ブートストラップメソッドGlobal.asaxを呼び出すことができます:RegisterGlobalFilters

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new SessionSecurityAttribute
        {
            MyDbConn = DependencyResolver.Current.GetService<MyDbConn>()
        });
}

SessionSecurityAttributeこれにより、DB 接続を備えた がデフォルトですべてのアクションに追加され、コード行を繰り返す必要がなくなります。

于 2013-08-08T22:46:17.373 に答える
0

独自のカスタム ISessionIDManager を実装してみてください: http://msdn.microsoft.com/en-us/library/system.web.sessionstate.isessionidmanager.aspx

検証では、それがまだ有効かどうかを確認し、そうでない場合は false を返します。

于 2013-08-08T22:53:15.577 に答える