2011-11-25 7 views
10

私はここにしばらく滞在していたにもかかわらず、これは私の初めての質問です。だから私に優しくしてください。このカスタムプリンシパルはベースコントローラにありますかASP.NET MVC 3は非常に効率が悪いですか?

私はPrincipalというカスタムを作成したいので、現在のユーザーに関する情報を標準よりも少しだけ保存して、あまり頻繁にデータベースに移動する必要はありません。それは私が後にしているかなり標準的なものです。最初のインスタンスで電子メールアドレスとユーザーIDを言うだけです。

オブジェクトをキャッシュに保存することを決めました。セッションに保存することはお勧めしません。

また、Userオブジェクトをキャストし続ける必要もないので、コントローラのUserオブジェクトをオーバーライドしたかったのです。だから私はちょうどUser.UserIdに行き、何かを保証することができます。

public class MyPrincipal : IPrincipal 
{ 
    public MyPrincipal(IIdentity ident, List<string> roles, string email, Guid userId) 
    { 
     this._identity = ident; 
     this._roles = roles; 
     this._email = email; 
     this._userId = userId; 
    } 

    IIdentity _identity; 

    public IIdentity Identity 
    { 
     get { return _identity; } 
    } 

    private List<string> _roles; 

    public bool IsInRole(string role) 
    { 
     return _roles.Contains(role); 
    } 

    private string _email; 

    public string Email 
    { 
     get { return _email; } 
    } 

    private Guid _userId; 

    public Guid UserId 
    { 
     get { return _userId; } 
    } 
} 

そして、私はこのようなベースコントローラがあります:

public class BaseController : Controller 
    { 
     protected virtual new MyPrincipal User 
     { 
      get 
      { 
       if (base.User is MyPrincipal) 
       { 
        return base.User as MyPrincipal; 
       } 
       else 
       { 
        return new MyPrincipal(base.User.Identity, new List<string>(0), "", Guid.Empty); 
       } 
      } 
     } 

     protected override void OnAuthorization(AuthorizationContext filterContext) 
     { 
      if (User != null) 
      { 
       if (User.Identity.IsAuthenticated) 
       { 
        if (User.Identity is FormsIdentity) 
        { 
         FormsIdentity id = base.User.Identity as FormsIdentity; 
         MyPrincipal principal = (MyPrincipal)filterContext.HttpContext.Cache.Get(id.Name); 
         if (principal == null) 
         { 
          MembershipUser user = Membership.GetUser(); 

          // Create and populate your Principal object with the needed data and Roles. 
          principal = new MyPrincipal(id, Roles.GetRolesForUser(id.Name).ToList(), user.Email, (Guid)user.ProviderUserKey); 
          filterContext.HttpContext.Cache.Add(
          id.Name, 
          principal, 
          null, 
          System.Web.Caching.Cache.NoAbsoluteExpiration, 
          new System.TimeSpan(0, 30, 0), 
          System.Web.Caching.CacheItemPriority.Default, 
          null); 
         } 
         filterContext.HttpContext.User = principal; 
         System.Threading.Thread.CurrentPrincipal = principal; 
         base.OnAuthorization(filterContext); 
        } 
       } 
      } 
     } 
    } 

をあなたが見ている場合は、すぐにユーザーが持っているかのことを理解するだから私はこのようなカスタムプリンシパルを作成し

ログインしていない場合Userオブジェクトへのコールは、このコードを実行する必要があります:

return new MyPrincipal(base.User.Identity, new List<string>(0), "", Guid.Empty); 

これは私には非常に非効率的ですが、欠落しているものについては空のオブジェクトを作成するだけです。

正常に動作します。

私はこれが実際に大丈夫かどうかを知りたいと思うので、性能と効率について肛門でなくてはいけませんか、あるいは恐怖が正しいとしたらどうしたらいいですか? [「人生を得よう!」と言ってはいけません。]

+4

[クヌース](http://en.wikipedia.org/wiki/Program_optimization#When_to_optimizeを)忘れないでください... "時期尚早の最適化は諸悪の根源です。"つまり、パフォーマンスの問題を実際に見たことがありますか? –

+0

+1いいです。いいえ、私はしていません。しかし、問題は、コードの厄介な行を見るまで、私はそれがすべて動作するようにしたことでかなりスマートに感じていたことです。うわー!私は本当に肛門です!私は、BBC Microでコーディングを開始したのは、クロックサイクルが少なくても間にあったことだと思います。 –

答えて

6

いいえ - このコードでは、特に顕著なパフォーマンススタンドポイントから間違ったことはありません。オブジェクトのPLENTYがASP.NETのバックエンドに作成されている場合、単一のオブジェクトはバケット内のドロップです。クラスのインスタンス化は非常に高速ですので、私はそれについて心配しません。

なぜここでセッションを無視していますか?セッション情報に有効期限がないため、シーンの後ろに余分なチェックはありません。 out of procセッションサーバーを使用していない限り、オブジェクトのシリアル化はありません(キャッシュなし)。 キャッシュはすべてのユーザーに適用されます。つまり、ユーザーごとにキャッシュされている間違ったプリンシパルを返すコードエラーが発生する可能性はわずかです(わずかですが)。

あなたが(ちょうどMVCベースではない)が、すべての要求のためにこれが利用できる場合、私はこの投稿は、使用のものであってもよいApplication_PostAuthenticateRequest

+0

+1 Thanks Adam。セキュリティ上の配慮以外に、セッションを無視している特別な理由はありません。私は意図的に 'Application_PostAuthenticateRequest'にそれを含めませんでした。私のコードでは、css、images、javascriptなどのリクエストのために実行されるでしょう。そうですか?保護が必要な画像は、MVCの 'FileContentResult'メソッドによって提供され、したがって、まだカバーされています。 –

2

でこれを設定することを検討します。認証チケットにuserdataを使用していることに注目してください。

ASP.NET MVC - Set custom IIdentity or IPrincipal

+0

ありがとうございます。私はすでにフォーム認証チケットを使用していることを知っていますが、別の場所に保存することを提案している場合を除き、クッキーを使用せずにやりたかったのです。 –

関連する問題