Tanımlama bilgisi kimlik doğrulamasını kullanarak bir oturum açma mekanizması oluşturun ve kimliğiniz doğrulanmadıysa yeniden yönlendirilecek bir mekanizma oluşturun

Sayfa güncel :
Sayfa oluşturma tarihi :

Çalışma ortamı

Visual Studio
  • Visual Studio Topluluğu 2022
ASP.NET Çekirdek (MVC, Razor Sayfaları)
6.0

İlk başta

Bu sefer ASP.NET Core, oturum açma kimlik doğrulama mekanizması olarak çerez kimlik doğrulamasını kullanacaktır. Tanımlama bilgisi kimlik doğrulamasını geleneksel form kimlik doğrulamasına benzer şekilde düşünebilirsiniz.

ASP.NET Core için başka bir kimlik doğrulama mekanizması ASP.NET Core Identity'dir. Formları kullanarak kimlik doğrulamaya ek olarak, bu, API'lerle kimlik doğrulamanıza, harici oturum açma hizmetlerini kullanmanıza, parolaları yönetmenize ve sıfırlamanıza vb. olanak tanır. Birçok özelliği kullanabilirsiniz. Ancak, bu sefer sadece basit bir giriş ekranı oluşturma açısından, biraz abartılı bir kimlik doğrulama mekanizması olacaktır. Bu sefer kullanmayacağız.

Bu sefer tanıtılan çerez kimlik doğrulama ipuçlarında, oturum açmadığınız sürece oturum açma ekranından başka bir şey görüntüleyemezsiniz. Başka bir ekrana gitmeye çalışırsanız, giriş ekranına yönlendirileceksiniz. Giriş yaparsanız, diğer ekranları görüntüleyebilirsiniz.

Şu an için giriş ekranına kullanıcı adınızı ve şifrenizi girerek giriş yapabilirsiniz. Kullanıcı kimlik doğrulamasının kendisi geçici bir yer olarak uygulanır. Bu durumda, ana odak noktası çerez kimlik doğrulamasının uygulanmasıdır, bu nedenle şifrenin doğru olup olmadığı gibi belirleme sürecinin özü esas değildir.

Bu ipucu, programın yalnızca bir bölümünü açıklar. Kodun tamamı için programın tamamını indirin. Ayrıca hem MVC hem de Razor Pages çerçevelerini kapsar.

Proje oluşturma

Visual Studio'yu başlatın ve yeni bir proje oluşturun.

Razor Sayfalar için ASP.NET Core Web App'i seçin veya MVC için Core Web App (Model-View-Controller) ASP.NET seçin.

Seçtiğiniz bir proje adı ve proje için bir konum belirtin.

Kimlik doğrulama türü için "Yok" seçeneğini seçin. Başka bir kimlik doğrulamasını seçerseniz ASP.NET Core Identity kullanırsınız. Ayarlarla işiniz bittiğinde, "Oluştur" düğmesini tıklayın.

Projeyi oluşturduktan sonra, hata ayıklama yürütüldüğünde aşağıda gösterilen ekran görüntülenecektir. Bu ekrana göre bir program oluşturacağız.

Programı Düzenle.cs (Razor Pages, MVC Ortak)

Tanımlama bilgisi kimlik doğrulaması için gerekli tanımları Program.cs'a ekleyin. Eklenecek ad alanları aşağıdaki gibidir:

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;

Eklenecek kod aşağıda verilmiştir builder.Services .

// === 省略 ===

// 「Razor Pages」のコード
// builder.Services.AddRazorPages();
// 「MVC」のコード
// builder.Services.AddControllersWithViews();

// ※ここから追加

// Cookie による認証スキームを追加する
builder.Services
  .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
  .AddCookie();

builder.Services.AddAuthorization(options =>
{
  // AllowAnonymous 属性が指定されていないすべての画面、アクションなどに対してユーザー認証が必要となる
  options.FallbackPolicy = new AuthorizationPolicyBuilder()
    .RequireAuthenticatedUser()
    .Build();
});

// ※ここまで追加

var app = builder.Build();

// === 省略 ===

AddAuthenticationAddCookie ve yöntemini çalıştırarak çerez kimlik doğrulamasını etkinleştirebilirsiniz. Şema adını değiştirmeniz gerekmiyorsa, CookieAuthenticationDefaults.AuthenticationScheme belirtin.

AddAuthorization Yöntem için belirtirseniz options.FallbackPolicy RequireAuthenticatedUser Tüm sayfalara, tüm denetleyicilere ve eylemlere kimlik doğrulaması gerektiren bir ilke uygulayabilirsiniz. Giriş ekranı dışında herhangi bir şey için kimlik doğrulama istemek istiyorsanız, kodu azaltmak ve açıklamadaki hataları önlemek açısından faydalı bir yöntemdir. Giriş ekranı için ayrıca kimlik doğrulama gerektirmeyen kod yazmanız gerekecektir.

için kod aşağıdadır app .

// === 省略 ===

app.UseRouting();

app.UseAuthentication(); // [追加] 認証
app.UseAuthorization(); // 認可

// 「Razor Pages」のコード
// app.MapRazorPages();
// 「MVC」のコード
// app.MapControllerRoute(
//     name: "default",
//     pattern: "{controller=Home}/{action=Index}/{id?}");

// === 省略 ===

Uygulamaya app.UseAuthentication() kimlik doğrulama işlevi eklemek istediğimiz için ekleyeceğiz. Açıklama konumu, MSDN belgelerine göredir. UseAuthorization() öğesini seçin. Bunun dışında, hala bir şablon.

Razor Pages projeleri için programlar

Oturum açma sayfası oluşturma (Pages/Account/Login.cshtml.cs)

Dosya oluşturma

Bir oturum açma sayfası oluşturun. Dosya yolu "/Pages/Account/Login.cshtml" olarak oluşturulmalıdır. Bunun nedeni, varsayılan oturum açma yolunun böyle olmasıdır. Bu yolu değiştirmek isterseniz, Program.cs yönteminin bağımsız değişkenini AddCookie ayarlayarak bunu yapabilirsiniz.

Menüden oluşturmak yerine diğer dosyaları kopyalayarak oluşturabilirsiniz, ancak bu durumda lütfen programı doğru şekilde düzeltin.

Kullanıcıların oturum açmadan oturum açma sayfasına erişmesine izin ver

Program.cs Tüm sayfalara yalnızca oturum açtığınızda erişilebildiğinden, oturum açmasanız bile erişebilmeniz için yalnızca oturum açma sayfasını ayarlamanız gerekir.

AllowAnonymous Öznitelikler eklenerek, kimliği doğrulanmamış olsa bile hedef sayfaya erişilebilir. AllowAnonymous Öznitelikler, tanımlama bilgisi kimlik doğrulamasıyla ilgili olmayan API işlemleri gibi oturum açma ekranı dışındaki başka yerlerde de kullanılabilir.

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Security.Claims;

namespace AspNetCoreCookieAuthenticationRazorPages.Pages.Account
{
  [AllowAnonymous]
  public class LoginModel : PageModel
  {
  }
}

Giriş almak için bir değişken oluşturma

Giriş yaptığınızda, şifrenizi girdiğiniz için bu değerleri alabilmek için kullanıcı adınızı beyan edersiniz.

// 省略

[AllowAnonymous]
public class LoginModel : PageModel
{
  /// <summary>ユーザー名。</summary>
  [BindProperty]
  [Required]
  [DisplayName("ユーザー名")]
  public string UserName { get; set; } = "";

  /// <summary>パスワード。</summary>
  [BindProperty]
  [Required]
  [DataType(DataType.Password)]
  [DisplayName("パスワード")]
  public string Password { get; set; } = "";
}

Oturum açma kimlik doğrulaması için bir kullanıcı adı ve parola tanımlayın

Başlangıçta, bir veritabanında vb. saklanacaktı, ancak bu sefer kullanıcı yargısı ana odak noktası olmadığı için geçici bir yer olarak yapacağım.

// 省略

[AllowAnonymous]
public class LoginModel : PageModel
{
  // 省略

  /// <summary>仮のユーザーデータベースとする。</summary>
  private Dictionary<string, string> UserAccounts { get; set; } = new Dictionary<string, string>
    {
      { "user1", "password1" },
      { "user2", "password2" },
    };
}

Giriş işlemi

/// <summary>ログイン処理。</summary>
public async Task<ActionResult> OnPost()
{
  // 入力内容にエラーがある場合は処理を中断してエラー表示
  if (ModelState.IsValid == false) return Page();

  // ユーザーの存在チェックとパスワードチェック (仮実装)
  // 本 Tips は Cookie 認証ができるかどうかの確認であるため入力内容やパスワードの厳密なチェックは行っていません
  if (UserAccounts.TryGetValue(UserName, out string? getPass) == false || Password != getPass)
  {
    ModelState.AddModelError("", "ユーザー名またはパスワードが一致しません。");
    return Page();
  }

  // サインインに必要なプリンシパルを作る
  var claims = new[] { new Claim(ClaimTypes.Name, UserName) };
  var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
  var principal = new ClaimsPrincipal(identity);

  // 認証クッキーをレスポンスに追加
  await HttpContext.SignInAsync(principal);

  // ログインが必要な画面にリダイレクトします
  return RedirectToPage("/Index");
}

Bu, giriş düğmesine bastıktan sonraki kimlik doğrulama işlemidir. Kullanıcı adı ve parola eşleşirse, kimlik doğrulama mümkündür.

Açıklanan kod,ClaimClaimsIdentityClaimsPrincipal kimlik doğrulaması için gereken en düşük koddur ve HttpContext.SignInAsync Yöntemi çağırarak bir tanımlama bilgisi oluşturulur ve kimliği doğrulanır.

Ek talepler gerekiyorsa veya çerezin süre sonu gerekiyorsa, ek parametreler eklenir.

Giriş yaptıktan sonra, kimlik doğrulamanın gerekli olduğu /Index yere yönlendirilirsiniz.

Oturumu kapatma işlemi

/// <summary>ログアウト処理。</summary>
public async Task OnGetLogout()
{
  // 認証クッキーをレスポンスから削除
  await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}

Logout Bir işleyici ile erişildiğinde, oturumu kapatmak için işlenir. HttpContext.SignOutAsync Yöntemi çağırarak, çerezi silebilir ve oturum açmadığınız bir duruma geri döndürebilirsiniz.

Görünüm Oluşturma

Görünüşü dikkate almıyoruz. Aşağıda gösterildiği gibi kullanıcı adınızı ve şifrenizi girmek için alanlar ekleyin ve oturum açmak için bir düğme yerleştirin. Ayrıca, test için oturum açmadan erişmek için /Index bir bağlantınız olmalıdır.

Kullanıcı adı ve şifrenin girilmesi zahmetli olduğundan, başlangıç değeri ayarlanır.

@page
@model AspNetCoreCookieAuthenticationRazorPages.Pages.Account.LoginModel
@{}

<form asp-action="Login">
  <div class="row m-1 g-3">
    <div class="col-sm-6 offset-sm-3">
      <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    </div>
  </div>

  <div class="row m-1 g-3">
    <div class="col-sm-6 offset-sm-3">
      <label asp-for="UserName" class="form-label"></label>
      <input asp-for="UserName" class="form-control" value="user1" />
      <span asp-validation-for="UserName" class="text-danger"></span>
    </div>
  </div>
  <div class="row m-1 g-3">
    <div class="col-sm-6 offset-sm-3">
      <label asp-for="Password" class="form-label"></label>
      <input asp-for="Password" class="form-control" value="password1" />
      <span asp-validation-for="Password" class="text-danger"></span>
    </div>
  </div>
  <div class="row m-1 g-3">
    <div class="col-sm-6 offset-sm-3">
      <button type="submit" class="btn btn-primary">ログイン</button>
    </div>
  </div>
  <div class="row m-1 g-3">
    <div class="col-sm-6 offset-sm-3">
      <a asp-page="/Index">認証が必要な画面へ直接リンク</a>
    </div>
  </div>
</form>

@section Scripts {
  @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

Oturum kapatma bağlantısı oluşturma (/Pages/Shared/_Layout.cshtml)

Ana ekranda herhangi bir değişiklik yapmayacağız, ancak gezinme çubuğuna bir çıkış bağlantısı koyacağız. Ayrıca, test için, oturumu kapatmadan sizi giriş ekranına götüren bir bağlantı gönderin.

<!-- 中略 -->
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
  <ul class="navbar-nav flex-grow-1">
    <li class="nav-item">
      <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
    </li>
    <!-- ここから追加 -->
    <li class="nav-item">
      <a class="nav-link text-dark" asp-page="/Account/Login" asp-page-handler="Logout">ログアウト</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-page="/Account/Login">ログアウトせずログインへ</a>
    </li>
    <!-- ここまで追加 -->
  </ul>
</div>
<!-- 中略 -->

Razor Pages kodu için bu kadar.

MVC Projeleri için Programlar

Oturum Açma Modeli Oluşturma

Giriş ekranında girilen değerleri almak için bir model oluşturdunuz.

namespace AspNetCoreCookieAuthenticationMvc.Models
{
  public class LoginModel
  {
    /// <summary>ユーザー名。</summary>
    [Required]
    [DisplayName("ユーザー名")]
    public string UserName { get; set; } = "";

    /// <summary>パスワード。</summary>
    [Required]
    [DataType(DataType.Password)]
    [DisplayName("パスワード")]
    public string Password { get; set; } = "";
  }
}

AccountController Oluşturma

Oturum açma ekranını oluşturmak için gereken denetleyicileri ve eylemleri oluşturun. Denetleyici adını AccountController olarak oluşturun. Bunun nedeni, varsayılan olarak, oturum açma ekranındaki denetleyici adının ve eylem adının "~/Account/Login" olarak ayarlanmış olmasıdır. Bu yolu değiştirmek isterseniz, bunu Program.cs'daki yöntemin AddCookie seçeneklerinde yapabilirsiniz. Şimdilik varsayılan ayarlarla devam edeceğiz.

İlk olarak Controller tarafını oluşturalım.

using AspNetCoreCookieAuthenticationMvc.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

namespace AspNetCoreCookieAuthenticationMvc.Controllers
{
  /// <remarks>
  /// <see cref="AllowAnonymous"/> 属性は Cookie 認証していなくてもアクセスできる Action (Controller) であることを示す。
  /// </remarks>
  [AllowAnonymous]
  public class AccountController : Controller
  {
  }
}

AllowAnonymous Öznitelik verildiğinde, içindeki tüm eylemler kimlik doğrulaması yapılmadan gerçekleştirilebilir. Bu, kimlik doğrulaması olmadan yalnızca oturum açma ekranına erişmenizi sağlar.

AllowAnonymous Öznitelikler, oturum açma ekranı dışındaki diğer yerlerde tanımlama bilgisi kimlik doğrulamasıyla ilgili olmayan yalnızca API denetleyicilerinde de kullanılabilir.

Ardından, oturum açabilecek kullanıcıları ve şifreleri tanımlayın. Başlangıçta, bir veritabanında vb. saklanacaktı, ancak bu sefer kullanıcı yargısı ana odak noktası olmadığı için geçici bir yer olarak yapacağım.

[AllowAnonymous]
public class AccountController : Controller
{
  /// <summary>仮のユーザーデータベースとする。</summary>
  private Dictionary<string, string> UserAccounts { get; set; } = new Dictionary<string, string>
    {
      { "user1", "password1" },
      { "user2", "password2" },
    };
}

Aşağıda, oturum açma ekranını görüntüleyen bir eylem yer almaktadır. Yalnızca görüntülendiğinden, görünümü olduğu gibi döndürür.

/// <summary>ログイン画面を表示します。</summary>
public IActionResult Login() => View();

Giriş yaparken işlenecek kod aşağıdadır.

/// <summary>ログイン処理を実行します。</summary>
[HttpPost]
public async Task<IActionResult> Login(LoginModel model)
{
  // 入力内容にエラーがある場合は処理を中断してエラー表示
  if (ModelState.IsValid == false) return View(model);

  // ユーザーの存在チェックとパスワードチェック (仮実装)
  // 本 Tips は Cookie 認証ができるかどうかの確認であるため入力内容やパスワードの厳密なチェックは行っていません
  if (UserAccounts.TryGetValue(model.UserName, out string? getPass) == false || model.Password != getPass)
  {
    ModelState.AddModelError("", "ユーザー名またはパスワードが一致しません。");
    return View(model);
  }

  // サインインに必要なプリンシパルを作る
  var claims = new[] { new Claim(ClaimTypes.Name, model.UserName) };
  var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
  var principal = new ClaimsPrincipal(identity);

  // 認証クッキーをレスポンスに追加
  await HttpContext.SignInAsync(principal);

  // ログインが必要な画面にリダイレクトします
  return RedirectToAction(nameof(HomeController.Index), "Home");
}

Bu, giriş düğmesine bastıktan sonraki kimlik doğrulama işlemidir. Kullanıcı adı ve parola eşleşirse, kimlik doğrulama mümkündür.

Açıklanan kod,ClaimClaimsIdentityClaimsPrincipal kimlik doğrulaması için gereken en düşük koddur ve HttpContext.SignInAsync Yöntemi çağırarak bir tanımlama bilgisi oluşturulur ve kimliği doğrulanır.

Ek talepler gerekiyorsa veya çerezin süre sonu gerekiyorsa, ek parametreler eklenir.

Giriş yaptıktan sonra, kimlik doğrulamanın gerekli olduğu ~/Home/Index yere yönlendirilirsiniz.

Son olarak, çıkış işlemi eklenir.

/// <summary>ログアウト処理を実行します。</summary>
public async Task<IActionResult> Logout()
{
  // 認証クッキーをレスポンスから削除
  await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

  // ログイン画面にリダイレクト
  return RedirectToAction(nameof(Login));
}

HttpContext.SignOutAsync Yöntemi çağırarak, çerezi silebilir ve oturum açmadığınız bir duruma geri döndürebilirsiniz.

Görünüm oluşturma (oturum açma formu) (/Views/Account/Login.cshtml)

Login Görünüm eklemek için eylemi sağ tıklatın. Başka bir dosyadan kopyalayarak da oluşturabilirsiniz.

Görünüşü dikkate almıyoruz. Aşağıda gösterildiği gibi kullanıcı adınızı ve şifrenizi girmek için alanlar ekleyin ve oturum açmak için bir düğme yerleştirin. Ayrıca, test için oturum açmadan erişmek için Home/Index bir bağlantınız olmalıdır.

Kullanıcı adı ve şifrenin girilmesi zahmetli olduğundan, başlangıç değeri ayarlanır.

@model LoginModel
@{}

<form asp-action="Login">
  <div class="row m-1 g-3">
    <div class="col-sm-6 offset-sm-3">
      <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    </div>
  </div>

  <div class="row m-1 g-3">
    <div class="col-sm-6 offset-sm-3">
      <label asp-for="UserName" class="form-label"></label>
      <input asp-for="UserName" class="form-control" value="user1" />
      <span asp-validation-for="UserName" class="text-danger"></span>
    </div>
  </div>
  <div class="row m-1 g-3">
    <div class="col-sm-6 offset-sm-3">
      <label asp-for="Password" class="form-label"></label>
      <input asp-for="Password" class="form-control" value="password1" />
      <span asp-validation-for="Password" class="text-danger"></span>
    </div>
  </div>
  <div class="row m-1 g-3">
    <div class="col-sm-6 offset-sm-3">
      <button type="submit" class="btn btn-primary">ログイン</button>
    </div>
  </div>
  <div class="row m-1 g-3">
    <div class="col-sm-6 offset-sm-3">
      <a asp-controller="Home" asp-action="Index">認証が必要な画面へ直接リンク</a>
    </div>
  </div>
</form>

@section Scripts {
  @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

Oturum kapatma bağlantısı oluşturma (/Views/Shared/_Layout.cshtml)

Ana ekranda herhangi bir değişiklik yapmayacağız, ancak gezinme çubuğuna bir çıkış bağlantısı koyacağız. Ayrıca, test için, oturumu kapatmadan sizi giriş ekranına götüren bir bağlantı gönderin.

<!-- 中略 -->
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
  <ul class="navbar-nav flex-grow-1">
    <li class="nav-item">
      <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
    </li>
    <!-- ここから追加 -->
    <li class="nav-item">
      <a class="nav-link text-dark" asp-controller="Account" asp-action="Logout">ログアウト</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-controller="Account" asp-action="Login">ログアウトせずログインへ</a>
    </li>
    <!-- ここまで追加 -->
  </ul>
</div>
<!-- 中略 -->

MVC kodu için bu kadar.

Operasyonun onaylanması

Bu, çerez kimlik doğrulamasının gereken minimum uygulamasını tamamlar. Çalıştırmayı deneyin ve nasıl çalıştığını görün. Davranış, oturum açıp açmadığınıza bağlı olarak değişmelidir. Basit bir örnek olarak, aşağıdaki davranışı görebilirsiniz.

İşlem işlem sonucu
Giriş yapmadan eve git Giriş ekranına yönlendir
Oturum açma Ana ekrana git
Evden çıkış yapın ve giriş yapmadan eve gidin Giriş ekranına yönlendir
Evden çıkış yapmadan ve giriş yapmadan eve gidin Ana ekrana git