はじめに
業務で ASP.Net Core MVC を使っていたのですが、RazorPage でウェブアプリを作ったことはなかったので、勉強かねて仮想的なECサイトを作っていました。
その中で、いくつかハマった事をまとめておこうと思います。
今回は、アクセス制限のかけ方についてまとめます。
想定している状況
デジタル作品をアップロードして、販売できるECサイトを想定して解説します。
フォルダおよびURLの構成
以下は、ソリューション内のフォルダ構成で、カッコ内はURLです。
解説に必要な部分だけ示しています。
なお、フォルダ構成と URL は一致しているわけではありません。
例えば、カートページは Purchase フォルダ内のページですが、 /Cart でアクセスできるような状況を想定しています。
/
├── Areas/
│ └── Seller/
│ └── Pages/
│ ├── Items/
│ │ └── Manage/
│ │ ├── Index.cshtml(/Seller/Items/Manage)
│ │ ├── ...
│ │
│ └── Register.cshtml(/Seller/Items/Register)
├── Pages/
│ ├── Purchase/
│ │ ├── Cart.cshtml(/Cart)
│ │ ├── Payment.cshtml(/Purchase/Payment)
│ │ ├── Confirm.cshtml(/Purchase/Confirm)
│ │ ├── ...
│ │
│ └── User
│ ├── Purchase.cshtml(/User/Purchase)
│ ├── Profile.cshtml(/User/:Uid/Profile)
│ ├── ...
│
└── StartUp.cs
アクセス制限の設定方法
ここでは、StartUp.cs 内で設定する方法を解説します。
以下のコードは、すべて ConfigureService
内に記述します。
販売者関連ページ(/Areas/Seller/)
Seller エリアにあるすべてのページは、ログインしていて、なおかつロールに"Seller"が設定されているユーザーのみアクセスできるように設定します。
事前に、ポリシーを追加しておきます。
services.AddAuthorization(
{
// アクセス制限用ポリシーを追加
options.AddPolicy("SellerPolicy", policy => policy.RequireRole("Seller"));
});
このアクセスポリシーを、Seller エリアに適用します。
エリアに承認規則を設定するには、AuthorizeAreaFolder
を使います。
フォルダーパスは、エリアフォルダを基準にした相対パスを設定します。
AuthorizeAreaFolder("エリア名", "フォルダーパス", "ポリシー")
実際のコードは以下のようになります。
services.AddMvc().AddRazorPagesOptions(options =>
{
// 販売者の作品関連ページ
options.Conventions.AuthorizeAreaFolder("Seller", "/Items", "SellerPolicy");
});
購入関連ページ(/Pages/Purchase/)
以下のような承認規則を設定します。
『購入関連のページは、ログインユーザー以外アクセスできないようにしたいが、カートページだけはログインしていないユーザーもアクセスできるようにする』
この場合、規則を設定する順番が重要になります。
まず始めに、Purchase フォルダーに対してログインユーザー以外アクセスできないように設定します。
その後、カートページに対して、AllowAnonymousToPage
を使って、だれでもアクセスできるように設定をしすます。
AllowAnonymousToPage("ページ(.cshtml)パス")
実際のコードは以下のようになります。
services.AddMvc().AddRazorPagesOptions(options =>
{
// 購入関連ページ
options.Conventions.AuthorizeFolder("/Purchase");
// カートページはログインしていなくても許可
options.Conventions.AllowAnonymousToPage("/Purchase/Cart");
// NOTE: まとめて以下のように書いても良い
// options.Conventions
// .AuthorizeFolder("/Purchase")
// .AllowAnonymousToPage("/Purchase/Cart");
});
Authorize~ よりも AllowAnonymous~ の方が強いので、先に .AllowAnonymousToFolder("/Purchase")
とした後、.AuthorizePage("/Purchase/カード以外のページ")
とやっても Purchase 以下のページはだれでもアクセスできてしまいます。
登録ユーザー関連ページ(/User/)
ユーザー関連ページの購入作品一覧ページのみ、ログインしているユーザー本人がアクセスできるように設定します。
特定のページにのみ承認規則を設定するには、AuthorizePage
を使います。
AuthorizePage("ページパス")
実際のコードは以下のようになります。
services.AddMvc().AddRazorPagesOptions(options =>
{
// 購入作品一覧ページ
options.Conventions.AuthorizePage("/User/Purchase");
});
コード全体
services.AddAuthorization(
{
// アクセス制限用ポリシーを追加
options.AddPolicy("SellerPolicy", policy => policy.RequireRole("Seller"));
});
services.AddMvc().AddRazorPagesOptions(options =>
{
// 販売者の作品関連ページ
options.Conventions.AuthorizeAreaFolder("Seller", "/Items","SellerPolicy");
// 購入関連ページ
options.Conventions.AuthorizeFolder("/Purchase");
// カートページはログインしていなくても許可
options.Conventions.AllowAnonymousToPage("/Purchase/Cart");
// 購入作品一覧ページ
options.Conventions.AuthorizePage("/User/Purchase");
});
参考
他にもアクセス制限のかけ方はあります。詳しく知りたい方は、公式ページを参照してください。
公式 - Razor Pages authorization conventions in ASP.NET Core
未完成ですが、デジタルデータを販売できるECサイトを想定したプロジェクトを用意したので、該当するファイルへのリンクも貼っておきます。