見出し画像

【覚書】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()
       {
       
       }
   }
}

いいなと思ったら応援しよう!