1

現在、データベースからアクセス許可を取得できるように、[Authorize] フィルターの拡張に取り組んでいます。すべてが機能しますが、パフォーマンスの問題は確かです。データベースにクエリを送信して許可を求めるたびに、これを決定する最良の方法ではありません。そこで、これらのデータをセッションに入れることを考えました。データベースからのデータを、データベースだけでなく、私が尋ねることができるセッションオブジェクト(LINQ)に入れる最速の方法は何ですか。

これは次のようになります。

var _allowedRolesDB = context.sec_RolesInCAs
                .Where(rl => rl.MenuControlName == controllRights && rl.MenuActionName == actionRights)
                .Select(rl => rl.RoleName);

            foreach (var r in _allowedRolesDB)
            {
                RolesDB = RolesDB + r.ToString() + ",";
            }

しかし、私はに変更したい

var _allowedRolesDB = MySuperSessionSomethink
.Where(rl => rl.MenuControlName == controllRights && rl.MenuActionName == actionRights)
                .Select(rl => rl.RoleName);

            foreach (var r in _allowedRolesDB)
            {
                RolesDB = RolesDB + r.ToString() + ",";
            }

MySuperSessionSomethink は、データベースから一度だけ取得したデータを保持します。どうすればこれを行うことができますか?助けを求める送信。


より大きな画像

Ok。より大きな画像を表示します。全体のアイデアは、カスタム承認フィルターを作成することです。

    [CustomAuthAttribute("Home,Index", Roles = "SuperAdministrator")]
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";

        return View();
    }

これの目標は何ですか。すべての利点に加えて、権限に関する情報をデータベースに保持するなどの追加機能を持つ承認属性を作成します。

今私がしていることは次のとおりです。

public CustomAuthAttribute(params string[] controllerAction)
{
        IPrincipal user = HttpContext.Current.User;
        string userName = user.Identity.Name;
        **... some code .. and take all allowed roles and check it have permissions** 
        var _allowedRolesDB = context.sec_RolesInCAs
            .Where(rl => rl.MenuControlName == controllRights && rl.MenuActionName == actionRights)
            .Select(rl => rl.RoleName);

        foreach (var r in _allowedRolesDB)
        {
            RolesDB = RolesDB + r.ToString() + ",";
        }
        **... some code .. thesame withs single users**

}

この後、私は使用します

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
   **... can acces or not part of code ...**
   if (_rolesSplit.Any(user.IsInRole))
   {
        return true;
    }
}

しかし、問題があります。データベースにアクセス許可について尋ねるたびに、この私見は最善の方法ではありません。今、私の考えは、1人のユーザーのすべての権限を取得し、承認されたときに彼をセッションに入れることです。たぶん私は間違っていて、この方法では問題が発生しますが、データベースに保管して、常にアクセス許可について尋ねるのも良い考えではありません:)。では、データベースに 1 つか 2 つの質問をしただけで、データを取得してコードで使用する方がよいのではないでしょうか?

4

1 に答える 1

0

まず第一に、セッションではなく、これらをキャッシュに追加したいようです。これらは、ユーザーに固有ではなく、アプリケーションに対してグローバルに見えます。メニューコントロール/アクションによってロールのルックアップを行っているので、ルックアップとしてそれらをキャッシュに追加するだけです。

string action = controlRights + actionRights;
string allowedRoles = Cache[action];
if (allowedRoles == null) 
{
    allowedRoles = String.Join(",", context.sec_RolesInCAs
        .Where(rl => rl.MenuControlName == controlRights && rl.MenuActionName == actionRights)
        .Select(rl => rl.RoleName)
        .ToArray());
    Cache[action] = allowedRoles;
}

これにより、2番目のリクエストのキャッシュから、指定されたコントロール/アクションに許可されたロールが提供されます。

于 2012-03-19T10:57:40.697 に答える