0

このコードで私が目にする問題は、それがたくさん再利用されるということです。認証されたユーザー(サイト管理者を除く)によって編集/作成されているものはすべて、その「スタジオ」オブジェクトにのみアクセスできます。

皆さんへの私の質問。これをどのようにリファクタリングして、サービス層をクライアントの知識から抽象化できるようにしますか。後でスタンドアロンデスクトップアプリケーションでサービスレイヤーを再利用する予定です。

私の間違ったやり方に光を当ててください!大変感謝しております。

AuthorizeOwnerAttribute.cs(AuthorizeAttribute)

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    // Get the authentication cookie
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = httpContext.Request.Cookies[cookieName];

    // If the cookie can't be found, don't issue the ticket
    if (authCookie == null) return false;

    // Get the authentication ticket and rebuild the principal & identity
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    string[] userData = authTicket.UserData.Split(new[] { '|' });

    int userId = Int32.Parse(userData[0]);
    int studioID = Int32.Parse(userData[1]);
    GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
    WebPrincipal userPrincipal = new WebPrincipal(userIdentity, userId, studioID);
    httpContext.User = userPrincipal;

    return true;
}

私の「ユーザー」コントローラー内で、所有者を必要とするすべてのメソッドにこの属性をアタッチします

    [AuthorizeOwner]
    public ActionResult Edit(int Id)
    {
        IUser user = userService.GetById(HttpContext.User, Id);
        return View(user);
    }

これで、サービスレイヤーで、渡されたIPrincipalが、要求されているオブジェクトにアクセスできるかどうかを確認しています。これは臭いがするところです:

UserService.cs

    public IUser GetById(IPrincipal authUser, int id)
    {
        if (authUser == null) throw new ArgumentException("user");

        WebPrincipal webPrincipal = authUser as WebPrincipal;
        if (webPrincipal == null) throw new AuthenticationException("User is not logged in");

        IUser user = repository.GetByID(id).FirstOrDefault();
        if (user != null)
        {
            if (user.StudioID != webPrincipal.StudioID) throw new AuthenticationException("User does not have ownership of this object");
            return user;
        }

        throw new ArgumentException("Couldn't find a user by the id specified", "id");
    }
4

1 に答える 1

2

実際の ID を Cookie に保存するかどうかはわかりませんが、これは少し露出しすぎています。セッションハッシュを使用してそのデータを保存し、サーバー上に保持して公開しないようにする傾向があります。

また、(userID を渡すことによって) Model を使用して、返されるオブジェクト、つまり、一致する studioID を持つオブジェクトを決定します。そうすれば、コントローラーは「GetObjects(int id)」を呼び出すだけで済み、何もアクセスできない場合は、null または空のコレクションが返されます。それは私にとってよりきれいに感じます。

于 2009-11-05T15:30:23.367 に答える