20

Editユーザーが作成したデータを次のように編集できるコントローラーメソッドがあります...

public ActionResult Edit(int id)
{
    Submission submission = unit.SubmissionRepository.GetByID(id);
    User user = unit.UserRepository.GetByUsername(User.Identity.Name);

    //Make sure the submission belongs to the user
    if (submission.UserID != user.UserID)
    {
        throw new SecurityException("Unauthorized access!");
    }

    //Carry out method
}

このメソッドは正常に機能しますが、すべてのコントローラーのEditメソッドを配置するのは少し面倒です。各テーブルには常にがあります。そのため、属性またはその他のメカニズムを使用してUserIDこれを自動化し、コードをよりクリーンにする簡単な方法があるかどうか疑問に思いました。[Authorize]

4

4 に答える 4

31

はい、カスタムのAuthorize属性を使用してこれを実現できます。

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        var rd = httpContext.Request.RequestContext.RouteData;

        var id = rd.Values["id"];
        var userName = httpContext.User.Identity.Name;

        Submission submission = unit.SubmissionRepository.GetByID(id);
        User user = unit.UserRepository.GetByUsername(userName);

        return submission.UserID == user.UserID;
    }
}

その後:

[MyAuthorize]
public ActionResult Edit(int id)
{
    // Carry out method
}

また、データベースに再度アクセスしないように、アクションパラメータとしてカスタム属性にフェッチしたこの送信インスタンスをフィードする必要があると仮定します。次の操作を実行できます。

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        var rd = httpContext.Request.RequestContext.RouteData;

        var id = rd.Values["id"];
        var userName = httpContext.User.Identity.Name;

        Submission submission = unit.SubmissionRepository.GetByID(id);
        User user = unit.UserRepository.GetByUsername(userName);

        rd.Values["model"] = submission;

        return submission.UserID == user.UserID;
    }
}

その後:

[MyAuthorize]
public ActionResult Edit(Submission model)
{
    // Carry out method
}
于 2012-06-14T16:20:39.903 に答える
2

アクション/コントローラーからロジックを引き出し、そのロジックを処理するドメインクラスを構築することをお勧めします。

アクションメソッドは、実際には、ビューからのデータの取得とビューへのデータの送信のみを処理する必要があります。ニーズを処理するのに十分な汎用性のあるものを作成できますが、単一責任の原則に従うこともできます。

public class AuthorizedToEdit 
{
     protected override bool AuthorizeCore(string user, int itemId)
     {
         var userName = httpContext.User.Identity.Name;

         var authUsers = SubmissionRepository.GetAuthoriedUsers(itemId);

         return authUsers.Contains(user);
     }
}

これにより、後で管理者ユーザーのようなものを許可する柔軟性を得ることができます。

于 2012-06-14T16:44:10.917 に答える
0
@if (Request.IsAuthenticated && User.IsInRole("Student"))
    {
    @Html.ActionLink("Edit", "Edit", new { id = item.StdID })
    }

私の場合、loggedInユーザーは学生です。つまり、ログインリクエストが認証されていて、彼の役割が学生である場合は、編集用のリンクにアクセスできるようにします。

以下では、通常のユーザーまたは管理者に編集を実行させることができます。

@if(Request.IsAuthenticated && User.IsInRole("Student") || 
User.IsInRole("Administrator"))
{
 @Html.ActionLink("Edit", "Edit", new { id = item.StdID })
}
于 2019-03-30T11:33:39.197 に答える
-1

を読むことをお勧めしますAuthorizeAttributeここを参照)。また、この投稿を見たことがありますか?認証属性の内部をオーバーライドする方法と、IPrincipalおよびIIdentityを使用する方法について説明します。

于 2012-06-14T16:22:34.083 に答える