2

カスタムユーザーセッションオブジェクトを格納するように.NETMVC3プロジェクトをセットアップしようとしています(後で他のアクションでカスタムプリンシパルオブジェクトからアクセスできます)次の手順に従いました: ASP.NETMVC-カスタムIIdentityを設定しますまたはIPrincipal (LukePの言うこと-カスタムメンバーシップなども必要でした)

私のログインアクションでは、次のようなものがあります。


if (provider.ValidateUser(model.UserName, model.Password))
{
        // setup principal 
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        string userData = serializer.Serialize(provider.GetSession());

        FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
             1,
             model.UserName,
             DateTime.Now,
             DateTime.Now.AddMinutes(15),
             false,
            userData);

        string encTicket = FormsAuthentication.Encrypt(authTicket);
        HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
        Response.Cookies.Add(faCookie);

        if (!String.IsNullOrEmpty(returnUrl))
        {
            return Redirect(returnUrl);
        }
        else
        {
            return RedirectToAction("Index", "Home");
        }
}
else
{
    ModelState.AddModelError("", "The user name or password provided is incorrect.");
}

これは基本的にユーザーオブジェクトを取得し(provider.GetSession()は外部認証サービスからカスタムユーザーセッションオブジェクトを返します)、それをFormsAuthenticationTicketに保存します

問題は、外部サービスからのユーザーセッションオブジェクトが4Kbを超えていることです(約7Kbが暗号化されています)。何が起こっているのかというと、サイズが原因でCookieがブラウザに保存されないということです。

このユーザーセッションオブジェクトをどこかに保存する他の安全な方法はありますか?データベースにクエリを実行し続ける必要はありませんか?セッションに保存するのは安全ではないと聞きました(セッションハイジャックのため、メンバーシップから切り離されているため)。では、他にどのような選択肢がありますか?

カスタムユーザーセッションオブジェクトのサイズを縮小できません。プロパティがすべてのシステムレイヤー呼び出しに依存しているため、これはオプションではありません。

よろしく、マーティン

4

1 に答える 1

3

ユーザーが権限のあることを行うたびにフォーム認証を検証する必要があるため、ユーザーのセッションオブジェクトに保存できなかった理由がわかりません。

セッションに保存したくない場合は、静的辞書を作成してそこにデータを保存できます。

using System.Collections.Concurrent;

// Class level declaration.
static ConcurrentDictionary<string, object> UserData =
        new ConcurrentDictionary<string, object>();

// Inside your magic method.
if (provider.ValidateUser(...)) {
  object providerSession = provider.GetSession();
  string userId = Guid.NewGuid().ToString("n");

  UserData.TryAdd(userId, providerSession);

  FormsAuthenticatonTicket authTicket = new FormsAuthenticatonTicket(
    1,
    model.UserName,
    DateTime.Now,
    DateTime.Now.AddMinutes(15),
    false,
    userid);

  // ...
}

そこから、userIdフォーム認証チケットに保存されている情報に基づいてプロバイダー セッション データを検索できます。objectプロバイダーが何を返すかわからないため、辞書に格納されているオブジェクトを標準にしました。より具体的なものである場合は、代わりにそのクラスを使用してください。

于 2013-01-22T06:12:21.113 に答える