1

私はこれについて多くの経験を持っていません、そして私はあなたたちから良い提案を得ることを本当に望んでいます。次のセキュリティシナリオを実装する必要があり、それを実行するための最良の方法を知りたいです。

従業員、上司、部門マネージャーがいると想像してみてください。従業員と上司の両方に、所属する部門マネージャーに基づいて、それを指すManagerIdが割り当てられています。

スーパーバイザーユーザーがログインするときに、彼と同じManagerIdに属する従業員のレコードのみを表示するようにします。別のManagerIdユーザーを持つ別のスーパーバイザーがログインしてURLに他の従業員の情報を手動でパンチした場合(例:wwww.domain.com/employee/details/ {id})、彼のManagerId!=従業員のManagerIdアクセスを制限したいので。

それは意味がありますか?

次のようなすべてのActionMethodsのチェックを入力し始めました。

public ActionResult Details(int id)
{
    var employee = employeeRepository.Get(id)
    var user = (CustomIdentity)ControllerContext.HttpContext.User.Identity;

    if(employee.managerId == user.managerId)
    {
        Do whatever...
    }   
    else    
    {
        Not allowed
    }
}

しかし、すべてのActionMethodsにそれを入力するのは冗長で、ただ..えーと...もっと良い方法があるはずだと私は知っています。

4

2 に答える 2

2

過去に同様の問題がありました。これは、オブジェクトごとのアクセス許可と見なすものです。私がしたことは、次のようなオブジェクトにメンバーを追加することでした:

public bool CanUserAccess(User user) {
    return managerId == user.managerId;
}

次に、制御されたリソースへのアクセスを提供する各アクションの上部で:

public ActionResult Details(int id)
{
    var employee = employeeRepository.Get(id)
    var user = (CustomIdentity)ControllerContext.HttpContext.User.Identity;
    if(!employee.CanUserAccess(user))
        return new HttpUnauthorizedResult();

    // Normal logic here
}

これは確かに完璧ではありませんが、アクセス許可の処理を一元化し、将来複雑さを簡単に増やすことができます (チェーンへのアクセスの許可、HR の特別なルールなど)。User.Identityまた、別のオーバーロード/拡張機能を記述して、もう少し自動化するためにプロパティにアクセスすることもできます (または、少なくとも型変換を処理します)。

私は ACL を扱っていたので、アクションの基本的な性質 (読み取り、書き込み、削除、作成など) を指定する追加のメソッド/パラメーターが必要でした。

于 2012-04-26T18:31:46.653 に答える
2

ここに解決策があります。少しクリーンアップする必要がありますが、必要なものはすべて提供されるはずです。

カスタム ActionFilter を作成し、メソッドをそれで装飾します。

[ManagerIdAuthentication]
public ActionResult Details(int id)
{
     // Gets executed if the filter allows it to go through.
}

次のクラスは別のライブラリに作成できるため、この検証が必要なすべてのアクションに含めることができます。

public class ManagerIdAuthentication : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // the next line needs improvement, only works on an httpGet since retrieves
        // the id from the url.  Improve this line to obtain the id regardless of 
        // the  method (GET, POST, etc.)
        var id = filterContext.HttpContext.Request.QueryString["id"];

        var employee = employeeRepository.Get(id);
        var user = filterContext.HttpContext.User.Identity;
        if (employee.managerId  == user.managerId)
        {
            var res = filterContext.HttpContext.Response;
            res.StatusCode = 402;
            res.End();
            filterContext.Result = new EmptyResult();  //may use content result if want to provide additional info in the error message.
        }
        else
        {
            // OK, let it through.
        }
    }
}
于 2012-04-26T18:36:21.527 に答える