2017-05-18 26 views
0

権限がコントローラレベルで渡され、ビューレベルで失敗するASP.NET Core 2.0 Webアプリケーションで奇妙な動作が発生しています。ASP.NET Core 2.0でビューベース認証を使用する方法

これはASP.NET Core 2.0のバグですか、私のコードで何か間違っていますか?

//コントローラ

情報で成功した認証:(ユーザー名):Microsoft.AspNetCore.Authorization.DefaultAuthorizationServiceは、[1] 認証は、ユーザーのために成功しました。

//コントローラ

情報へのエントリー:引数((ヌル) )とMicrosoft.AspNetCore.Mvc.Internal.ControllerActionInvoker [1] 実行アクションメソッドHomeController.Index(BAMS) - にModelStateが有効である

...

//ビューで失敗

情報:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService [2] Authorizユーザーのために失敗しました:(ユーザー名)。 Startup.csで

ConfigureServices:

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

HomeController.cs:

[Authorize(Policy="HasName")] 
public class HomeController : Controller 
{ 
    public IActionResult Index(){ 
     return View(); 
    } 
} 

HasNameRequirement:

public class HasNameRequirement : IAuthorizationRequirement { 
    public HasNameRequirement() { } 
} 

HasNameHandler:

public class HasNameHandler : AuthorizationHandler<HasNameRequirement> 
{ 
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasNameRequirement requirement) 
    { 
     var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext; 
     if (mvcContext != null) 
     { 
      var name = mvcContext.HttpContext.User.Identity.Name; 
      if(name != null && name != "") 
      { 
       context.Succeed(requirement); 
      } 
      else 
      { 
       context.Fail(); 
      } 
     }   

     return Task.CompletedTask; 
    } 
} 

_Layout.cshtml:

@if (await AuthorizationService.AuthorizeAsync(User, "HasName")) 
{ 
    ... 
} 

_ViewImports.cshtml:

@using Microsoft.AspNetCore.Authorization 
@inject IAuthorizationService AuthorizationService 
+0

なぜあなたはビューでauthZをやっていますか? – Mardoxx

+0

@Mardoxx意図は、適​​切な主張を持つ人にしか見えない特定のリンクやコンテンツが存在するということです。私は、コントローラがとにかくそれらをロックアウトしようとしている場合、User Administrationページへのリンクを表示したくありません。コードの実際のバージョンでは、私は異なるポリシーを持っています。これは、ビューベースの認可の機能性をテストしていただけです。私は他の提案にもオープンしていますが、各ポリシーごとに別々のビューを作成することは、私がやりたいことではありません。 – Ryukerg

答えて

1

問題がHasNameHandlerにありました。

var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext; 

この行は、私の認証ブロックがMVCコンテキストがある場合にのみ機能するように作られています。ビューはMVCコンテキストにアクセスできないため、ビューベースの認可はcontext.Succeed()を呼び出さずに認可を終了しました。

これを削除し、その代わりにメソッドに渡されたAuthorizationContextを使用しました。

var name = context.User.Identity.Name; 
if(name != null && name != ""){ 
    context.Succeed(requirement); 
} 
else { 
    context.Fail(); 
} 
関連する問題