Buat mekanisme untuk diubah hala jika anda tidak log masuk menggunakan pengesahan kuki (ASP.NET Teras 3.0)

Laman dikemaskini :
Tarikh penciptaan halaman :

Persekitaran

Visual Studio
  • Komuniti studio visual 2019
ASP.NET Core
3.0 atau lebih baharu

Pengesahan cookie boleh digunakan dalam .NET Core 2.2 atau lebih awal, tetapi tips kami termasuk kod khusus untuk .NET Core 3.0 dan kemudian.

Pada mulanya

ASP.NET Core menggunakan pengesahan cookie sebagai mekanisme pengesahan log masuk. Anda boleh memikirkan pengesahan kuki sebagai sesuatu yang serupa dengan pengesahan borang tradisional.

Satu lagi cara untuk mengesahkan ASP.NET Core adalah identiti teras ASP.NET. Selain pengesahan menggunakan borang, pengesahan api, Perkhidmatan log masuk Luaran, pengurusan kata laluan dan menetapkan semula, dan lain-lain. Anda boleh menggunakan banyak fungsi. Walau bagaimanapun, dari pandangan hanya membuat skrin login yang mudah kali ini, ia menjadi mekanisme pengesahan sedikit dibesar-besarkan Saya tidak menggunakannya pada masa ini.

Dalam petua untuk pengesahan kuki, anda tidak boleh memaparkan apa-apa selain daripada skrin log masuk melainkan anda log masuk. Jika anda cuba untuk pergi ke skrin yang berbeza, anda akan dihalakan semula ke skrin log masuk. Anda juga boleh melihat skrin lain dengan log masuk.

Sebaik sahaja anda memasukkan nama pengguna dan kata laluan anda pada skrin log masuk, anda boleh log masuk. Pengesahan pengguna itu sendiri dilaksanakan dalam kedudukan sementara. Sejak pelaksanaan utama pengesahan cookie adalah untuk terakhir kali ini, proses penghakiman, seperti sama ada kata laluan yang betul, tidak penting.

Petua ini menyenaraikan program yang jarang. Muat turun atur cara yang lengkap untuk kod lengkap.

Cipta projek

Mulakan Visual Studio dan cipta projek baru.

image

Pilih aplikasi web Core ASP.net.

image

Tentukan sebarang nama projek dan lokasi projek.

image

Kali ini, kita akan menggunakan projek MVC, tetapi kebanyakan template lain boleh diganti.

Untuk pengesahan, pilih tiada pengesahan. Jika anda memilih pengesahan lain, anda akan menggunakan identiti teras ASP.NET.

image

Selepas anda mencipta projek dan nyahpepijat, skrin dalam Rajah di bawah muncul. Kami akan mencipta atur cara berdasarkan skrin ini.

image

Edit Startup.cs

Startup.cs Tambah definisi yang diperlukan untuk pengesahan cookie. Membungkus Use:

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

Anda boleh membolehkan pengesahan kuki dengan menjalankan kaedah Addpengesahan dan Addcookies. Tentukan Cookiepengesah. pengesah jika anda tidak perlu menukar nama skim secara khusus.

Kaedah addpemberikuasaan pilihan. Jika anda menentukan Requidipengesah kepada pengguna dalam dasar sandaran, Semua pengawal boleh mempunyai dasar yang diperlukan pengesahan yang dikenakan kepada tindakan. Ia juga berguna dalam erti kata bahawa Kod dikurangkan dan kesilapan penerangan dihalang jika pengesahan diperlukan selain daripada skrin log masuk. Hanya skrin log masuk akan menulis kod yang tidak memerlukan pengesahan secara individu.

public void ConfigureServices(IServiceCollection services)
{
  services.AddControllersWithViews();
  
  // Cookie による認証スキームを追加する
  services
    .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie();
  
  services.AddAuthorization(options =>
  {
    // AllowAnonymous 属性が指定されていないすべての Action などに対してユーザー認証が必要となる
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
      .RequireAuthenticatedUser()
      .Build();
  });
}

Tambah pengesahan pada permohonan anda. Tambah Usepengesahan (). Lokasi Perihalan adalah berdasarkan dokumentasi MSDN. Tempat di hadapan Usepemberikuasaan (). Semua yang lain kekal template.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  if (env.IsDevelopment())
  {
    app.UseDeveloperExceptionPage();
  }
  else
  {
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. ...
    app.UseHsts();
  }
  app.UseHttpsRedirection();
  app.UseStaticFiles();
  
  app.UseRouting();
  
  app.UseAuthentication(); // [追加] 認証
  app.UseAuthorization(); // 認可
  
  app.UseEndpoints(endpoints =>
  {
    endpoints.MapControllerRoute(
      name: "default",
      pattern: "{controller=Home}/{action=Index}/{id?}");
  });
}

Mewujudkan sebuah AccountController

Cipta pengawal dan tindakan yang anda perlukan untuk mencipta skrin log masuk. Nama pengawal dicipta sebagai AccountController. Ini adalah kerana secara lalai, nama pengawal dan nama tindakan skrin log masuk ditentukan untuk menjadi "~/Account/Login". Jika anda ingin menukar laluan ini, anda boleh mengubahnya dengan pilihan kaedah AddCookie di Startup.cs. Kami akan pergi melalui tetapan lalai.

image

Langkah pertama adalah untuk mencipta sisi pengawal. Dengan memberikan atribut AllowAnonymous , semua tindakan dalam hal itu boleh dilakukan walaupun mereka tidak disahkan. Ini hanya membenarkan skrin log masuk untuk dicapai tanpa pengesahan.

Atribut AllowAnonymous adalah bebas daripada pengesahan cookie sebagai lokasi selain daripada skrin log masuk. Ia juga boleh digunakan pada pengawal api sahaja.

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;

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

Takrifkan pengguna dan kata laluan yang boleh dilog masuk. Pada asalnya saya Simpan ke pangkalan data, tetapi kali ini penghakiman pengguna bukanlah fokus utama Aku membuatnya dengan set sementara.

/// <summary>仮のユーザーデータベースとする。</summary>
private Dictionary<string, string> UserAccounts { get; set; }

public AccountController()
{
  // 仮のユーザーを登録する
  UserAccounts = new Dictionary<string, string>
  {
    { "user1", "password1" },
    { "user2", "password2" },
  };
}

Ini adalah tindakan untuk memaparkan skrin log masuk. Kembalikan pandangan kerana ia hanya dipaparkan.

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

Proses pengesahan selepas menekan butang log masuk. Jika nama pengguna dan padanan kata laluan, ia boleh disahkan.

Kod berikut mentakrifkan tuntutan, identiti, dan Berinpal sebagai kod minimum yang diperlukan untuk pengesahan. Memanggil Httpkonteks. kaedah SignInAsync menjana cookie dan mengesahkan.

Jika tuntutan tambahan diperlukan atau kuki tamat tempoh, tambah parameter.

Selepas log masuk, kami telah dilencongkan ke ~/Home/Index, yang memerlukan pengesahan.

/// <summary>ログイン処理を実行します。</summary>
[HttpPost]
public async Task<IActionResult> Login(string userName, string password)
{
  // ユーザーの存在チェックとパスワードチェック (仮実装)
  // 本 Tips は Cookie 認証ができるかどうかの確認であるため入力内容やパスワードの厳密なチェックは行っていません
  if (UserAccounts.TryGetValue(userName, out string getPass) == false || password != getPass)
  {
    return View();
  }

  // サインインに必要なプリンシパルを作る
  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 RedirectToAction(nameof(HomeController.Index), "Home");
}

Masukkan proses log keluar. Anda boleh memadam kuki dan mengembalikannya kepada keadaan yang tidak dilog dengan memanggil Httpkonteks. SignOutAsync method.

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

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

Cipta paparan (Borang log masuk) (/Views/Account/Login.cshtml)

Oleh kerana kami tidak mengambil kira, tambah medan untuk memasukkan nama pengguna dan kata laluan anda, seperti yang ditunjukkan dalam Rajah di bawah, dan letakkan butang untuk log masuk. Anda juga harus meletakkan pautan untuk mengakses rumah/Indeks tanpa perlu log masuk untuk tujuan ujian.

Kerana ia menyusahkan untuk memasukkan nama pengguna dan kata laluan, nilai permulaan ditetapkan.

image

@{
  Layout = null;
}
<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width" />
  <title>Login</title>
</head>
<body>
  <form method="post">
    <input name="userName" type="text" placeholder="ユーザー名" value="user1" />
    <input name="password" type="password" placeholder="パスワード" value="password1" />
    <button type="submit">ログイン</button>
  </form>
  <p><a asp-controller="Home" asp-action="Index">認証が必要な画面へ直接リンク</a></p>
</body>
</html>

Cipta pautan log keluar (/Views/Shared/_Layout. cshtml)

Skrin utama tidak akan mengubah apa-apa, tetapi anda akan mempunyai pautan log masuk dalam Bar navigasi. Di samping itu, saya juga akan meletakkan pautan yang peralihan ke skrin log masuk tanpa melog keluar untuk tujuan ujian.

image

<!-- 中略 -->
<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">Logout</a>
    </li>
    <li class="nav-item">
      <a class="nav-link text-dark" asp-controller="Account" asp-action="Login">ログアウトせずログインへ</a>
    </li>
    <!-- ここまで追加 -->
  </ul>
</div>
<!-- 中略 -->

Semak operasi

Anda kini telah melengkapkan pelaksanaan minimum yang diperlukan untuk pengesahan cookie. Cuba untuk melakukannya dan melihat bagaimana ia berfungsi. Ia harus mengubah tingkah laku bergantung kepada sama ada anda log masuk atau tidak. Sebagai contoh yang mudah, saya fikir anda boleh melihat tingkah laku berikut.

Operasi keputusan operasi
Pergi ke rumah tanpa log masuk Ubah hala ke skrin Masuk
Log masuk Pergi ke skrin utama
Log keluar dari rumah dan pulang tanpa log masuk Ubah hala ke skrin Masuk
Jangan log keluar dari rumah dan pulang tanpa log masuk Pergi ke skrin utama