2017-06-26 23 views
0

私はグーグルとそのさまざまなバリエーションがありますが、私はまだ全く混乱していません。私は、特定の属性を持つすべてのアクションにカスタムヘッダーを追加したいだけです。シンプルに聞こえる?しかし、そうではありません。私は、次の書かれている:MVCのアクションのカスタムヘッダーを追加

[AttributeUsage(AttributeTargets.Method)] 
public class HelloWorldAttribute : ActionFilterAttribute 
{ 
    /// <inheritdoc /> 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     filterContext.HttpContext.Response.Headers["X-HelloWorld"] = string.Empty; 
    } 
} 

そして、それは彼らがControllerレベルに[Authorize]によって禁止されている場合を除き、すべての要求のために正常に動作します。

この属性をレベルControllerに使用して、このヘッダーを追加する必要のあるメソッド名を使用しようとしましたが、機能しません。 Authorizeは常に優先順位が高いようです。そしてあなたはそれが醜いことに同意することができます。

どうすればできますか?

+0

グローバルに登録するとどうなりますか?もしまだないなら。 – dcg

+0

@dcg私はコントローラのカップルにいくつかのメソッドのためだけに必要なので私はしないでください。だから、このヘッダを追加する必要のあるコントローラのホワイトリストをグローバルに登録し、それら以外のすべてをblaclistするよりも簡単です。 –

+2

さて、一歩踏み込んで、あなたが何をしているのか考えてみてください。誰かが何かを見ることを許可されていないときにヘッダーのコードを実行したいのですが?定義上、あなたが承認されていない場合、あなたはそれから機能を得るべきではなく、それはあなたのヘッダーを含みます。認可が「優先度が高い」というわけではありません。これは前述のことを達成するためにパイプラインの早期に実行されることです。 – JuanR

答えて

1

独自のauthorize属性を記述し、メモ自動化またはPolicyを追加できる場合はコードを処理できます。私は秀怠け者

ああ...ここ

まず

services.AddAuthorization(options => 
     { 
      options.AddPolicy("ReplaceHeader", 
           policy => policy.Requirements.Add(new ReplaceHeaderPolicy())); 
     }); 

     services.AddSingleton<IAuthorizationHandler, ReplaceHeaderHandler>(); 

をあなたのポリシーを登録し、コントローラ

にそれを使用するポリシー

public class ReplaceHeaderPolicy : IAuthorizationRequirement 
{ 

} 

public class ReplaceHeaderHandler : AuthorizationHandler<ReplaceHeaderPolicy> 
{ 
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ReplaceHeaderPolicy requirement) 
    { 

     if (!context.User.Identity.IsAuthenticated) 
     { 
      var fc = (FilterContext)context.Resource; 
      fc.HttpContext.Response.Headers["X-HelloWorld"] = string.Empty; 
     } 

     context.Succeed(requirement); 
     return Task.CompletedTask; 
    } 
} 

を追加

[Authorize] 
    [Authorize(Policy = "ReplaceHeader")] 
    public IActionResult Index() 
    { 
     return View(); 
    } 

不正アクセス

のためのアクセスを許可するために、第2の[承認]を削除し、私はそれを願っています

+0

URLを参照するより詳細を追加してください。 [レビュー](https://stackoverflow.com/review/first-posts/16531641)から。 – harshavmb

1

を助け問題は承認属性は、実際ので、あなたの他の属性は決して実行されているから、コントローラのメソッドに対してガードであるということです走るつもりです。

あなたは承認属性からスローされますセキュリティ例外を処理します。この

public class HandleUnauthorizedAttribute : HandleErrorAttribute 
{ 
    public override void OnException(ExceptionContext filterContext) 
    { 
     base.OnException(filterContext); 

     if (filterContext.Exception.GetType() != typeof(SecurityException)) return; 

     var controllerName = (string)filterContext.RouteData.Values["controller"]; 
     var actionName = (string)filterContext.RouteData.Values["action"]; 
     var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); 

     filterContext.Result = new ViewResult 
     { 
      ViewName = "Unauthorized", 
      ViewData = new ViewDataDictionary<HandleErrorInfo>(model), 
      TempData = filterContext.Controller.TempData 
     }; 
     filterContext.ExceptionHandled = true; 
     filterContext.HttpContext.Response.Clear(); 
     filterContext.HttpContext.Response.StatusCode = 403; 
     filterContext.HttpContext.Response.Headers.Add("X-HelloWorld", ""); 
     filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; 
    } 
} 

などのカスタム属性を追加することができます。

また、応答時にヘッダーを追加するカスタムAuthorize属性を記述することもできます。

+0

不運なことに、制御フローがここに落ちない –

関連する問題