2016-10-21 8 views
2

.Net/ASP.NET開発に慣れていて、グローバルレベルで追加したいカスタムポリシーを使用しようとしています。私が構築したポリシーの各コントローラに[Authorize]属性を追加する必要があります。すべてのコントローラとグローバルアクションのカスタムポリシーのauthorize属性を設定する

SuperAdminUsersというポリシーを作成し、グローバルレベルで設定するUserNamesRequirementのカスタム要件を使用します。すべてのコントローラとアクションにアクセスできるようにします。SuperAdminUsers

以下は私がstartup.csファイルで作成したポリシーです。上記config.Filters

services.AddAuthorization(
     option => 
     { 
      option.AddPolicy("Admin", policy => policy.RequireRole("DOMAIN\\GroupName")); 
      option.AddPolicy("SuperAdminUsers", policy => policy.Requirements.Add(new UserNamesRequirement("DOMAIN\\USER1", "DOMAIN\\USER2")) 
     } 
); 
// Add Custom filters 
services.AddMvc(
    config => 
    { 
     var policy = new AuthorizationPolicyBuilder(); 
     policy.Requirements.Add(new UserNamesRequirement("DOMAIN\\USER1")); 
       policy.Build(); 
       config.Filters.Add(new AuthorizeFilter(policy)); 
    } 
); 

、私はスクリーンショットの下で示されたエラーを取得:ここ

enter image description here

は私の顧客の要求であるのとクラスハンドル:

public class UserNamesRequirement : IAuthorizationRequirement 
{ 
    public UserNamesRequirement(params string[] UserNames) 
    { 
     Users = UserNames; 
    } 
    public string[] Users { get; set; } 
} 

protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserNamesRequirement requirement) 
{ 
     // var userName = context.User.FindFirst(ClaimTypes.NameIdentifier).Value; 
     var userName = context.User.Identity.Name; 

     if (requirement.Users.ToList().Contains(userName)) 
      context.Succeed(requirement); 
     return Task.FromResult(0); 
} 

をUPDATE 1:

以下のコードで起動ファイルを更新しますが、依然として承認することはできません。

services.AddMvc 
     (
      config => 
      { 
       var policyBuilder = new AuthorizationPolicyBuilder(); 
       policyBuilder.Requirements.Add(new UserNamesRequirement("DOMAIN\\USER1", "DOMAIN\\USER2")); 
       var policy = policyBuilder.Build(); 
       config.Filters.Add(new AuthorizeFilter(policy)); 
      } 
     ); 

コントローラ私がアクセスしようとしています:

注:ここでは

[Authorize(Policy = "Admins")] 
[Authorize(Policy = "SuperAdminUsers")] 
public class OperatingSystemsController : Controller 
{ 
    private readonly ServerMatrixDbContext _context; 

    public OperatingSystemsController(ServerMatrixDbContext context) 
    { 
     _context = context;  
    } 

    // GET: OperatingSystems 
    public async Task<IActionResult> Index() 
    { 
     return View(await _context.OperatingSystems.ToListAsync()); 
    } 
} 

は、私はstrの出力ログファイルでそれを見るものである私は、実際のドメインとユーザー名を削除しました。

Application started. Press Ctrl+C to shut down. 
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] 
     Request starting HTTP/1.1 GET http://localhost/demo/OperatingSystems/Create 
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1] 
     Authorization was successful for user: DOMAIN\USER1. 
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] 
     Authorization failed for user: DOMAIN\USER1. 
warn: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1] 
     Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. 
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1] 

すべてのヘルプは本当に感謝しています。

+0

すべてのコントローラに対して1つの基本クラスを作成し、そのクラスに対して[認可]のみを設定します。 – Eins

+0

したがって、私は基底クラスを作成し、Authorizeを追加します。この 'PublicクラスSearchController:Controller、BaseAuth {}'のようなすべてのコントローラに、それをちょうど埋め込んでいますか? – Ray

+0

私はこのBaseControllerを意味しました:Controller、 YourController:BaseController – Eins

答えて

2

フィルターは、すべてのコントローラーとアクションに対して許可属性を設定する1つの方法です。たとえば、ここには特定のユーザー名を必要とするポリシーがあります。

services.AddMvc(config => 
{ 
    var policy = new AuthorizationPolicyBuilder() 
        .RequireUserName("DOMAIN\\USERID") 
        .Build(); 

    config.Filters.Add(new AuthorizeFilter(policy)); 
}); 

AuthorizationFilterコンストラクタがpolicyないpolicyBuilderを期待するので、あなたが受信しているエラーが発生します。ここでは、より明確にするために変数名を変更したコードを示します。

services.AddMvc(config => 
{ 
    var policyBuilder = new AuthorizationPolicyBuilder(); 
    policyBuilder.Requirements.Add(new UserNamesRequirement("DOMAIN\\USER1")); 

    // this will NOT work 
    policyBuilder.Build(); 
    config.Filters.Add(new AuthorizeFilter(policyBuilder)); 

    // this will work 
    var policy = policyBuilder.Build(); 
    config.Filters.Add(new AuthorizeFilter(policy)); 

}); 
+0

ありがとうShaun。これは助けになりましたが、カスタムの 'handler'クラスと' requirement'クラスを利用するカスタムポリシーをどのように実装できますか?私は私の質問に私が得るエラーで詳細を追加しました。 – Ray

+1

@ray 'Build()'メソッドは 'policy'を返します。'policyBuilder'を' policy'に変更しません。私の編集によってこれが明らかになるかもしれません。 –

+0

ああ、今それは意味がある。 :)私を説明する時間を取ってくれてありがとう。私は本当にあなたの助けに感謝します。 – Ray

関連する問題