ASP.NET Core での単純な承認
ASP.NET Core での承認は、[Authorize]
属性とそのさまざまなパラメーターを使用して制御されます。 最も基本的な形式では、コントローラー、アクション、または Razor ページに [Authorize]
属性を適用して、そのコンポーネントへのアクセスを認証済みユーザーに限定します。
前提条件
この記事では、ASP.NET Core Razor Pages と MVC の基礎を理解していることを前提としています。 ASP.NET Core を初めてお使いになる場合は、次のリソースを参照してください。
- ASP.NET Core での Razor ページの概要
- ASP.NET Core MVC の概要
- チュートリアル: ASP.NET Core の Razor Pages の概要
- ASP.NET Core での Identity の概要
[Authorize]
属性を使用する
次のコードでは、AccountController
へのアクセスが認証済みユーザーに限定されます。
[Authorize]
public class AccountController : Controller
{
public ActionResult Login()
{
}
public ActionResult Logout()
{
}
}
コントローラーではなくアクションに承認を適用する場合は、アクション自体に AuthorizeAttribute
属性を適用します。
public class AccountController : Controller
{
public ActionResult Login()
{
}
[Authorize]
public ActionResult Logout()
{
}
}
これで、認証されたユーザーだけが Logout
関数にアクセスできます。
AllowAnonymous
属性を使用して、認証されていないユーザーによる個々のアクションへのアクセスを許可することもできます。 次に例を示します。
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
}
public ActionResult Logout()
{
}
}
これにより、認証済みか、未認証または匿名の状態かに関係なくすべてのユーザーがアクセスできる Login
アクションを除き、認証されたユーザーだけが AccountController
にアクセスできます。
警告
[AllowAnonymous]
を指定すると、承認ステートメントがバイパスされます。 [AllowAnonymous]
と任意の [Authorize]
属性を組み合わせた場合、[Authorize]
属性は無視されます。 次の例は、コントローラー レベルで [AllowAnonymous]
を適用する場合です:
- コントローラー上の同じコントローラーまたはアクション・メソッド上の
[Authorize]
属性からの許可要件はすべて無視されます。 - 認証ミドルウェアはショートサーキットされませんが、成功する必要はありません。
次のコードを使用すると、LogoutModel
Razor ページへのアクセスが、認証されたユーザーに限定されます。
[Authorize]
public class LogoutModel : PageModel
{
public async Task OnGetAsync()
{
}
public async Task<IActionResult> OnPostAsync()
{
}
}
すべてのユーザーの認証をグローバルに要求する方法の詳細については、「認証されたユーザーを要求する」を参照してください。
属性と Razor ページを承認する
AuthorizeAttribute を Razor ページ ハンドラーに適用することは "できません"。 たとえば、[Authorize]
は、OnGet
、OnPost
、または他のページ ハンドラーには適用できません。 ハンドラーごとに異なる承認要件を持つページには、ASP.NET Core MVC コントローラーの使用を検討してください。 さまざまな承認要件が必要な場合に MVC コントローラーを使用することは:
- 最も複雑でないアプローチです。
- Microsoft がお勧めするアプローチです。
MVC コントローラーを使用しない場合は、次の 2 つのアプローチを使用して、Razor ページ ハンドラー メソッドに承認を適用できます。
異なる承認を必要とするページ ハンドラーには、個別のページを使用します。 共有コンテンツを 1 つ以上の部分ビューに移動します。 可能であれば、これはお勧めのアプローチです。
共通ページを共有する必要があるコンテンツの場合は、IAsyncPageFilter.OnPageHandlerSelectionAsync の一部として承認を実行するフィルターを記述します。 PageHandlerAuth GitHub プロジェクトでこのアプローチを示します。
- AuthorizeIndexPageHandlerFilter によって承認フィルターが実装されます。
[TypeFilter(typeof(AuthorizeIndexPageHandlerFilter))] public class IndexModel : PageModel { private readonly ILogger<IndexModel> _logger; public IndexModel(ILogger<IndexModel> logger) { _logger = logger; } public void OnGet() { } public void OnPost() { } [AuthorizePageHandler] public void OnPostAuthorized() { } }
- [AuthorizePageHandler] 属性は、
OnPostAuthorized
ページ ハンドラーに適用されます。
public class AuthorizeIndexPageHandlerFilter : IAsyncPageFilter, IOrderedFilter { private readonly IAuthorizationPolicyProvider policyProvider; private readonly IPolicyEvaluator policyEvaluator; public AuthorizeIndexPageHandlerFilter( IAuthorizationPolicyProvider policyProvider, IPolicyEvaluator policyEvaluator) { this.policyProvider = policyProvider; this.policyEvaluator = policyEvaluator; } // Run late in the selection pipeline public int Order => 10000; public Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) => next(); public async Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) { var attribute = context.HandlerMethod?.MethodInfo?.GetCustomAttribute<AuthorizePageHandlerAttribute>(); if (attribute is null) { return; } var policy = await AuthorizationPolicy.CombineAsync(policyProvider, new[] { attribute }); if (policy is null) { return; } await AuthorizeAsync(context, policy); } #region AuthZ - do not change private async Task AuthorizeAsync(ActionContext actionContext, AuthorizationPolicy policy) { var httpContext = actionContext.HttpContext; var authenticateResult = await policyEvaluator.AuthenticateAsync(policy, httpContext); var authorizeResult = await policyEvaluator.AuthorizeAsync(policy, authenticateResult, httpContext, actionContext.ActionDescriptor); if (authorizeResult.Challenged) { if (policy.AuthenticationSchemes.Count > 0) { foreach (var scheme in policy.AuthenticationSchemes) { await httpContext.ChallengeAsync(scheme); } } else { await httpContext.ChallengeAsync(); } return; } else if (authorizeResult.Forbidden) { if (policy.AuthenticationSchemes.Count > 0) { foreach (var scheme in policy.AuthenticationSchemes) { await httpContext.ForbidAsync(scheme); } } else { await httpContext.ForbidAsync(); } return; } }
警告
PageHandlerAuth サンプル アプローチを使用しても、以下は実行 "されません"。
- ページ、ページ モデル、またはグローバルに適用される承認属性を使用した構成。 承認属性を構成すると、1 つ以上の
AuthorizeAttribute
またはAuthorizeFilter
インスタンスもページに適用した場合に、認証と承認が複数回実行されます。 - ASP.NET Core 認証および承認システムの rest と連携した作業。 このアプローチの使用がアプリケーションに対して正しく動作することを確認する必要があります。
Razor ページ ハンドラーで AuthorizeAttribute
をサポートする予定はありません。
ASP.NET Core