8

独自のカスタム Authorize 属性を実装しました。

この属性は、コントローラー レベルとアクション レベルの両方で適用されます。

これが私がする必要があることの例です:

[ClaimsAuthorize(Roles = "AdvancedUsers")]
public class SecurityController : Controller
{
    [ClaimsAuthorize(Roles = "Administrators")]
    public ActionResult AdministrativeTask()
    {
        return View();
    }

    public ActionResult SomeOtherAction()
    {
        return View();
    }
}

現在、管理者ロールを持っていても AdvancedUsers ロールを持っていないユーザーは、「管理タスク」を実行できません。

ユーザーがコントローラ レベルで許可されていない場合でも、アクション レベルでセキュリティ チェックを実行するようにこの動作を変更するにはどうすればよいですか?

今のところ、考えられる唯一の解決策は、2 つの属性を実装することです。1 つはコントローラーを保護するためのもので、もう 1 つはアクションを保護するためのものです。次に、Order プロパティを操作して、最初にアクション レベルでそれを実行します。

ただし、可能であれば、単一の属性を持つソリューションを希望します。

4

5 に答える 5

2

これは不可能です。MVC が承認フィルターで使用するロジックを想像してみてください。

  1. コントローラーが決定したら、そのコントローラーに適用される認可フィルターがあるかどうかを確認し、それを実行します。
  2. アクションがわかっている場合 - アクションに対して同じことを行います。

いずれの場合も、認証に失敗すると、パイプラインが短絡します。

于 2013-10-16T13:48:33.373 に答える
1

2 つの承認属性が必要です。1 つはすべての承認ロジックを備えた基本属性で、もう 1 つは基本属性から派生したもので、基本属性を上書きするためにのみ使用されます。

認可属性の例:

public class ClaimsAuthorizeAttribute : AuthorizeAttribute
{
    protected bool _canOverride = true;

    //...custom authorization code goes here.....

    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        //Don't authorize if the override attribute exists
        if (_canOverride && actionContext.ActionDescriptor.GetCustomAttributes<OverrideClaimsAuthorizeAttribute>().Any())
        {
            return;
        }
        base.OnAuthorization(actionContext);
    }

}


public class OverrideClaimsAuthorizeAttribute : ClaimsAuthorizeAttribute
    {
        public OverrideClaimsAuthorizeAttribute ()
            : base()
        {
            _canOverride = false;
        }

    }

基本認証属性では、OverrideClaimsAuthorizeAttribute が存在しない限り、通常どおり認証を行うように指示しています。OverrideClaimsAuthorizeAttribute が存在する場合は、_canOverride が false であるクラス (つまり、OverrideClaimsAuthorizeAttribute クラス自体) に対してのみ承認を実行します。

使用例:

[ClaimsAuthorize(Roles = "AdvancedUsers")]
public class SecurityController : Controller
{

    //Ignores the controller authorization and authorizes with Roles=Administrators
    [OverrideClaimsAuthorize(Roles = "Administrators")]
    public ActionResult AdministrativeTask()
    {
        return View();
    }


    //Runs both the controller and action authorization, so authorizes with Roles=Administrators AND Roles=AdvancedUsers
    [ClaimsAuthorize(Roles = "Administrators")]
    public ActionResult AdvancedAdministrativeTask()
    {
        return View();
    }

    //authorizes with controller authorization: Roles=AdvancedUsers
    public ActionResult SomeOtherAction()
    {
        return View();
    }
}
于 2013-12-21T17:37:51.523 に答える
0

この前の質問を確認してください。(@AndyBrownの回答、ケース2を確認してください)

簡単な方法として、( [AllowAnonymous]) を追加してコントローラー [Authorize] をオーバーライドしてから、新しいカスタム フィルターを追加して、この特定のアクションのロジックを確認することもできます。または、ロールをチェックするコードをそのすぐ中に追加することもできます。

于 2013-10-16T12:57:05.653 に答える