【覚書】ASP.NET Core Razor Pages での Identity を使用しない Cookie 認証
■動作環境
・Visual Studio Community 2019
・.NET Core 3.1
■Startup.cs
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace AspNetCoreTest
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
//Cookie認証のために追加
services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
//ログイン前に[Authorize]属性のページモデルに
//アクセスしようとした場合のリダイレクト先
options.LoginPath = "/Login";
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
//Cookie認証のために追加
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
}
■Login.cshtml
@page
@model AspNetCoreTest.Pages.LoginModel
@{
ViewData["Title"] = "Login";
}
<h1>Login</h1>
<form asp-page="Login">
<input asp-for="@Model.UserId" class="form-control" />
<input asp-for="@Model.Password" class="form-control" />
<input type="submit" class="btn btn-primary" />
</form>
■Login.cshtml.cs
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace AspNetCoreTest.Pages
{
public class LoginModel : PageModel
{
public string UserId { get; set; }
public string Password { get; set; }
public void OnGet()
{
//(検証コード)ログイン済みかどうかの判定ができる
System.Diagnostics.Debug.WriteLine(User.Identity.IsAuthenticated);
//(検証コード)ClaimTypes.Nameの値を取得できる
System.Diagnostics.Debug.WriteLine(User.Identity.Name);
//(検証コード)任意の文字列で名前をつけた値を取得できる
var entry = User.Claims.FirstOrDefault(c => c.Type == "userId");
if (entry != null) { System.Diagnostics.Debug.WriteLine(entry.Value); }
}
public async Task<IActionResult> OnPostAsync(string userId, string passWord)
{
//(検証コード)本来はDBを利用した認証処理などをここに記述
var userName = "テストユーザー";
Claim[] claims =
{
new Claim("userId", userId),
new Claim(ClaimTypes.Name, userName),
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
//ログイン
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
//ブラウザを閉じてもログインしたままにするか
IsPersistent = false,
//Cookieの有効期間(分)
ExpiresUtc = DateTime.UtcNow.AddMinutes(20),
});
//(検証コード)return前にはUser.Identity.IsAuthenticatedはTrueにならない
System.Diagnostics.Debug.WriteLine(User.Identity.IsAuthenticated);
//(検証コード)ログアウト
//await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
//任意のページへリダイレクト
return RedirectToPage("/Index");
}
}
}
■Index.cshtml.cs
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace AspNetCoreTest.Pages
{
//ログインしないとアクセスできないページモデル属性
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}