あなたが言ったように、OnValidatePrincipal
イベントでリクエストのデータにアクセスすることができます。だから、あなたはこのような何かを書くことができます:
OnValidatePrincipal = async (context) =>
{
if (context.Request.Path.Value.StartsWith("/teams/"))
{
var teamId = // get team id from Path;
if (user is not team member)
{
context.Response.StatusCode = 403;
}
}
}
しかし、私はあなたの要件がAuthorization
はなくAuthentication
関連していると思います。私はこの要求を処理するためにPolicy-Based Authorization
を使用します。例の方針は次のようにする必要があります:
要件とハンドラ:
public class TeamMemberHandler: AuthorizationHandler<TeamMemberRequirement>
{
private readonly IActionContextAccessor _accessor; // for getting teamId from RouteData
public TeamMemberHandler(IActionContextAccessor accessor)
{
_accessor = accessor;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TeamMemberRequirement requirement)
{
var teamId = // get teamId with using _accessor
if (user is not member of team(by teamId))
{
context.Fail();
}
return Task.FromResult(0);
}
}
public class TeamMemberRequirement : IAuthorizationRequirement
{
}
サービスの設定:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddAuthorization(options =>
{
options.AddPolicy("TeamMember",
policy => policy.Requirements.Add(new TeamMemberRequirement()));
});
services.AddSingleton<IAuthorizationHandler, TeamMemberHandler>();
}
最後に、コントローラの上にそれを使用する(またはしたい場合は、あなたがグローバルフィルタを追加することができます)
Authorize[(Policy = "TeamMember")]
public class TeamHomeController : Controller
{
// Authorize[(Policy = "AnotherPolicy")]
public IActionResult Index(){}
}
恐ろしい答え、ありがとう! さらに、これをさらに進めるには、パラメータ化可能なポリシーがありますか?ユーザーがGET '/ some/endpoint?teamId = 3'を送信するときに、何らかのデータを読み取るためのアクセス権を持っているという主張をユーザーが持っているとしましょう。次に、同じコントローラに対してPUTでそのデータを更新しようとします。これには、このデータを更新できるという主張が必要です。 したがって、これらのクレームタイプのポリシーをパラメータ化できますか?あるいは、それぞれのために新しい方針が必要でしょうか? – steamrolla
はい、更新のための新しいポリシーが必要です。更新アクションメソッドの上にそれを使用する必要があります。 –
Bah!それは、同じコードではあるが異なるデータで、1日の終わりに1トンの異なるポリシーになります。将来的にasp.netコアチームから強化されるかもしれませんか? – steamrolla