Sukurkite mechanizmą, kuris bus nukreiptas, jei neprisijungsite naudodami slapukų autentifikavimą (ASP.NET Core 3.0)

Puslapis atnaujintas :
Puslapio sukūrimo data :

Aplinkos

Visual Studija
  • Visual Studio bendruomenės 2019
ASP.NET branduolys
3.0 arba naujesnė versija

Slapukų autentifikavimas gali būti naudojamas .NET Core 2.2 arba ankstesnėje versijoje, tačiau mūsų patarimai apima kodą, specialiai skirtą .NET Core 3.0 ir naujesnei versijai.

Iš pradžių

ASP.NET Core naudoja slapukų autentifikavimą kaip prisijungimo autentifikavimo mechanizmą. Slapukų autentifikavimą galite laikyti kažkuo panašiu į tradicinį formų autentifikavimą.

Kitas būdas autentifikuoti ASP.NET core yra ASP.NET Core tapatybę. Be autentifikavimo naudojant formas, API autentifikavimą, išorinių prisijungimo paslaugas, slaptažodžių valdymą ir nustatymą iš naujo ir tt Galite naudoti daug funkcijų. Tačiau, atsižvelgiant į tiesiog padaryti paprastą prisijungimo ekraną šį kartą, jis tampa šiek tiek perdėtas autentifikavimas mechanizmas Šiuo metu jo nenaudoju.

Slapukų autentifikavimo patarimuose negalite rodyti nieko, išskyrus prisijungimo ekraną, nebent prisijungsite. Jei bandysite pereiti į kitą ekraną, būsite nukreipti į prisijungimo ekraną. Taip pat galite matyti kitus ekranus prisijungę.

Kai prisijungimo ekrane įvesite savo vartotojo vardą ir slaptažodį, galite prisijungti. Paties vartotojo autentifikavimas yra įdiegtas laikinai. Kadangi pagrindinis slapukų autentifikavimo įgyvendinimas yra paskutinis šį kartą, sprendimo procesas, pvz., ar slaptažodis yra teisingas, nėra būtinas.

Šie patarimai išvardija programą iš dalies. Atsisiųskite visą programą, skirtą visiškam kodui.

Projekto kūrimas

Paleiskite Visual Studio ir sukurti naują projektą.

image

pasirinkite ASP.NET pagrindinę žiniatinklio programą.

image

Nurodykite projekto pavadinimą ir projekto vietą.

image

Šį kartą naudosime mvc projektus, tačiau dauguma kitų šablonų gali būti pakeisti.

Autentifikavimui pasirinkite Nėra autentifikavimo. Jei pasirinksite kitą autentifikavimą, naudosite ASP.NET pagrindinio pašto vartotojo.

image

Sukūrę projektą ir jį suderinus, rodomas toliau pateiktoje iliustracijoje esantis ekranas. Mes sukursime programą, pagrįstą šiuo ekranu.

image

Redaguoti Startup.cs

Startup.cs pridėti slapukų autentifikavimui reikalingus apibrėžimus. Vardų sritys:

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;

Galite įgalinti slapukų autentifikavimą paleisdami AddAuthentication ir AddCookie metodus. Nurodykite CookieAuthenticationDefaults.AuthenticationScheme, jei jums nereikia keisti schemos pavadinimą ypač.

Addauthorization metodo parinktys. Jei "FallbackPolicy" nurodysite RequireAuthenticatedUser, Visi valdikliai gali turėti autentifikavimui reikalingą strategiją, taikomą veiksmui. Taip pat naudinga ta prasme, kad kodas yra sumažintas ir aprašo klaida yra užkirstas kelias, jei autentifikavimas yra būtinas, išskyrus prisijungimo ekraną. Tik prisijungimo ekrane bus parašyti kodą, kuris nereikalauja autentifikavimo atskirai.

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

Pridėkite autentifikavimą prie savo programos. Pridėti UseAuthentication(). Aprašo vieta yra pagrįsta MSDN dokumentacija. Vieta prieš UseAuthorization(). Visa kita lieka šablonu.

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?}");
  });
}

AccountController kūrimas

Sukurkite valdiklius ir veiksmus, kurių reikia norint sukurti prisijungimo ekraną. Valdiklio pavadinimas sukuriamas kaip AccountController. Taip yra todėl, kad pagal numatytuosius nustatymus prisijungimo ekrano valdiklio pavadinimas ir veiksmo pavadinimas yra "~/Account/Login". Jei norite pakeisti šį kelią, galite jį pakeisti addCookie metodo parinktis Startup.cs. Mes pereiti su numatytuosius nustatymus.

image

Pirmasis žingsnis yra sukurti valdiklio pusę. Suteikus atributą AllowAnonymous, visi jame esantys veiksmai gali būti atlikti, net jei jie nėra autentifikuoti. Tai leidžia pasiekti tik prisijungimo ekraną be autentifikavimo.

AllowAnonymous atributas nepriklauso nuo slapukų autentifikavimo kaip vietą, išskyrus prisijungimo ekraną. Jis taip pat gali būti naudojamas tik api valdikliuose.

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
  {
  }
}

Apibrėžkite vartotojus ir slaptažodžius, kuriuos galima prisijungti. Iš pradžių aš jį išsaugoti į duomenų bazę, tačiau šį kartą vartotojo sprendimas nėra pagrindinis dėmesys Aš tai laikinu rinkiniu.

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

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

Tai yra prisijungimo ekrano rodymo veiksmas. Pateikti rodinį taip, kaip yra, nes jis rodomas tik.

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

Autentifikavimo procesas paspaudus prisijungimo mygtuką. Jei vartotojo vardas ir slaptažodis sutampa, jis gali būti autentifikuotas.

Šis kodas apibrėžia pretenziją, tapatybę ir Pricinpal kaip minimalų autentifikavimui reikalingą kodą. Iškviesdami HttpContext.SignInAsync metodą generuoja slapuką ir autentifikuoja jį.

Jei reikia papildomų pretenzijų arba slapukų galiojimo laikas baigiasi, pridėkite parametrų.

Prisijungę, mes nukreipti į ~/Home/Index, kuris reikalauja autentifikavimo.

/// <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");
}

Įveskite atsijungimo procesą. Galite panaikinti slapuką ir grąžinti jį į neužregistruotą būseną paskambinę httpcontext.SignOutAsync metodu.

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

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

Rodinio kūrimas (prisijungimo forma) (/Views/Account/Login.cshtml)

Kadangi mes neatsižvelgiame į jį, pridėkite lauką, kad įvestumėte savo vartotojo vardą ir slaptažodį, kaip parodyta toliau pateiktame paveikslėlyje, ir įdėkite mygtuką, kad prisijungtumėte. Taip pat turėtumėte pateikti saitą, kad galėtumėte pasiekti namų / rodyklės neprisijungę testavimo tikslais.

Kadangi sunku įvesti vartotojo vardą ir slaptažodį, pradinė reikšmė yra nustatyta.

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>

Atsijungimo saito kūrimas (/Views/Shared/_Layout.cshtml)

Pradinis ekranas nieko nepakeis, bet naršymo juostoje turėsite atsijungimo nuorodą. Be to, aš taip pat įdėti nuorodą, kad perėjimai į prisijungimo ekraną be atsijungti bandymų tikslais.

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>
<!-- 中略 -->

Tikrinti operaciją

Dabar atlikote minimalų slapukų autentifikavimui reikalingą diegimą. Pabandykite tai padaryti ir pamatyti, kaip tai veikia. Ji turėtų pakeisti veikimą, priklausomai nuo to, ar esate prisijungęs, ar ne. Kaip paprastas pavyzdys, manau, kad jūs galite pamatyti tokį elgesį.

Operacija Operacijos rezultatai
Eiti namo neprisijungę Peradresavimas į prisijungimo ekraną
Prisijungti Eiti į pagrindinį ekraną
Atsijungti nuo namų ir eiti namo be prisijungimo Peradresavimas į prisijungimo ekraną
Neatsijungti nuo namų ir eiti namo be prisijungimo Eiti į pagrindinį ekraną