Razor Pagesでシンプルな認証機能を持つアプリケーションを作成する手順とコードを紹介します。
ユーザーIDやパスワードで認証してWebアプリケーションを利用させたい場合があります。
この記事では、ASP.NET Coreの認証機能を利用した非常にシンプルな認証機能のあるアプリケーションを作成する手順と
コードを紹介します。
ASP.NET Core アプリケーションを作成します。アプリケーションのフレームワークは .NET 6を利用します。
以下のファイル構成とします。
下記ファイル、コードを作成します。
@page
@model AuthenticationSimple.Pages.IndexModel
@{
}
<html>
<head>
<title>index</title>
</head>
<body>
<h1>index</h1>
<a href="Login">Login</a><br/>
<a href="Logout">Logout</a><br/>
<a href="Content">Content</a><br/>
</body>
</html>
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace AuthenticationSimple.Pages
{
public class IndexModel : PageModel
{
public void OnGet()
{
}
}
}
@page
@model AuthenticationSimple.Pages.LoginModel
@{
}
<html>
<head>
</head>
<body>
<h1>Login</h1>
<p>ログインしました。</p>
</body>
</html>
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
namespace AuthenticationSimple.Pages
{
public class LoginModel : PageModel
{
public void OnGet()
{
Claim[] claims = {
new Claim(ClaimTypes.NameIdentifier, "User"),
new Claim(ClaimTypes.Name, "ユーザー"),
};
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties {
IsPersistent = true
}
);
}
}
}
@page
@model AuthenticationSimple.Pages.LogoutModel
@{
}
<html>
<head>
</head>
<body>
<h1>Logout</h1>
<p>ログアウトしました。</p>
</body>
</html>
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
namespace AuthenticationSimple.Pages
{
public class LogoutModel : PageModel
{
public void OnGet()
{
HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}
@page
@model AuthenticationSimple.Pages.ContentModel
@{
}
<html>
<head>
</head>
<body>
<h1>コンテンツのページ</h1>
<p>ユーザー:@Model.OutUserName</p>
<p>コンテンツのページです</p>
<p>認証が必要なページです</p>
</body>
</html>
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;
namespace AuthenticationSimple.Pages
{
[Authorize]
public class ContentModel : PageModel
{
public string OutUserName { get; set; }
public void OnGet()
{
foreach (Claim c in User.Claims) {
if (c.Type == ClaimTypes.Name) OutUserName = c.Value;
}
}
}
}
using Microsoft.AspNetCore.Authentication.Cookies;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
WebApplication app = builder.Build();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
/Content
が認証が必要なページです。
ページモデルクラスに [Authorize]
属性を記述すると、認証が必要なページとして動作します。
[Authorize]
public class ContentModel : PageModel
{
/* 中略 */
}
ページ内に現在ログインしているユーザーの名前を表示するエリアを作成しています。OutUserName
プロパティにユーザーの名称を設定する動作にします。~
<body>
<h1>コンテンツのページ</h1>
<p>ユーザー:@Model.OutUserName</p>
<p>コンテンツのページです</p>
<p>認証が必要なページです</p>
</body>
ログインしているユーザーの情報は、ページモデルクラスの User
プロパティの Claims
オブジェクトに設定されています。
Claimsオブジェクト内の値は、Login.cshtml.csで設定したClaimオブジェクトの値が代入されています。
今回はユーザー名を取得してページに表示するため、Claims オブジェクトをループで走査し、TypeプロパティがClaimTypes.Name
である
Claimオブジェクトの値を取得してユーザー名として画面に表示します。
public void OnGet()
{
foreach (Claim c in User.Claims) {
if (c.Type == ClaimTypes.Name) OutUserName = c.Value;
}
}
ログインページになります。今回はIDやパスワードの入力なしに、ログインページにアクセスすると
ログイン済みとなる動作にします。
claims
変数にログインするユーザーの情報を設定します。今回は、NameIdentifier
に"User"、Name
に"ユーザー"の値を設定します。
ログイン後にClaimの値を取得して、ログインしているユーザーの情報をページに表示したりできます。
claims から、ClaimsIdentityオブジェクトを作成します。
ログインできたことにするには、HttpContext.SignInAsync()
メソッドを呼び出します。
第一引数に、認証スキーマ、第二引数に ClaimsPrincipalオブジェクト、第三引数に AuthenticationProperties オブジェクトを与えます。
public void OnGet()
{
Claim[] claims = {
new Claim(ClaimTypes.NameIdentifier, "User"),
new Claim(ClaimTypes.Name, "ユーザー"),
};
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties {
IsPersistent = true
}
);
}
Logout ページにアクセスするとログアウトとします。ログアウトする場合は、HttpContext.SignOutAsync()
メソッドを呼び出します。
public void OnGet()
{
HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
Program.csは通常のRazorPagesの初期化処理に加えて、builder.Services.AddAuthentication
を追加します。
また、UseCookiePolicy()
UseAuthentication()
UseAuthorization()
を追加します。
using Microsoft.AspNetCore.Authentication.Cookies;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
WebApplication app = builder.Build();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
プロジェクトを実行し、アプリケーションルートのURLにアクセスします。下図のページが表示されます。
はじめに、ログインしていない状態で、ログインが必要なページにアクセスしてみます。[Content]のリンクをクリックします。
ページは表示されず、(アプリケーションルートURL)/Account/Login?ReturnUrl=%2FContent
にリダイレクトされます。
アクセスしたページのURIがReturnUrl
パラメーターにセットされ、/Account/Login
にリダイレクトされる動作になっています。
アプリケーションルートのページに戻ります。ログインしてみます。[Login]のリンクをクリックします。
Loginページが表示され、ログインできました。
再度アプリケーションルートのURLに戻り、[Content]のリンクをクリックします。
ログイン状態になったため、ページの内容が表示されます。
ページ内に現在ログインしているユーザー名「ユーザー」の文字列も表示できています。
アプリケーションルートのページに戻り[Logout]リンクをクリックします。下図のページが表示され、ログアウトの処理が実行されます。
アプリケーションルートのページに戻り、再度[Content]のリンクをクリックします。ログアウト状態になっているため、
(アプリケーションルートURL)/Account/Login?ReturnUrl=%2FContent
にリダイレクトされます。
Program.csで UseAuthorization()
はUseRouting()
より後ろに記述する必要があります。
Program.csのコードが以下の場合、app.UseAuthorization()
がapp.UseRouting()
より手前にあるため、認証が必要なページに
アクセスするとエラーが発生します。
using Microsoft.AspNetCore.Authentication.Cookies;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
WebApplication app = builder.Build();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseRouting();
app.MapRazorPages();
app.Run();
プロジェクトを実行し、Contentページを表示すると以下のエラーが発生します。
UseRouting()
より後ろにUseAuthorization()
が記述されていれば、エラーは発生しません。
using Microsoft.AspNetCore.Authentication.Cookies;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
WebApplication app = builder.Build();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Webアプリケーション独自のアカウントでの認証画面を作成する場合は次の記事を参照してください。
Azure ADを利用した認証を実装する場合は次の記事を参照してください。