ASP.NETCoreIdentityなしでCookie認証を使用する

Uncategorized
887 words

公式サイトを見ながら試したのですが、なかなかに手こずったので、自分なりにやったことをまとめました。

環境

  • Windows 11 Home 21H2
  • Visual Studio Community 2022
  • フレームワーク: .NET 6.0

手順

プロジェクト作成

今回は「ASP.NET Core Web アプリ」で作業していきます。

プロジェクトの作成

プロジェクト名や保存場所等はお好みで変えてください。今回は「WebApplication1」で説明していきます。

プロジェクトの構成

  • フレームワークは「.NET 6.0」を選択。
  • 認証なし、これからCookie認証を入れてくので余分なコードが無い方が楽。
  • Dockerにチェック入れましたが、どっちでもいいです。Docker使わなくても問題なし。
  • 一番下の「Do not use top-level statements」にチェック入れました。これは .NET 6.0 からの機能で、Main メソッドが隠蔽されるので、チェックを入れて隠蔽されない状態で始めていきます。

追加情報の設定

RazorPages 削除

Razorページは使わないので削除。CSHTML嫌い。

Razorページの削除

「Program.cs」内からも RazorPages処理を削除。

  • builder.Services.AddRazorPages();
  • app.MapRazorPages();

RazorPages処理の削除

Cookie認証の作成

Cookie認証するためのAPIを作成します。

「Controllers」フォルダーを作り、その中に「AccountController.cs」を作成します。

Controllerの作成

「AccountController.cs」に次のソースをコピペします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

namespace WebApplication1.Controllers
{
[AllowAnonymous]
[ApiController]
[Route("api/[controller]/[action]")]
public class AccountController : ControllerBase
{
[HttpGet]
public ActionResult<string> GetUser()
{
var claims = HttpContext.User.Claims;
var userId = claims?.FirstOrDefault(x => x.Type.Equals(ClaimTypes.Name))?.Value;
return Ok(userId);
}

[HttpGet]
public async Task<ActionResult> Login([FromQuery] string userId)
{
if (!userId.Equals("abc"))
{
return Unauthorized();
}

var claims = new List<Claim>() { new Claim(ClaimTypes.Name, userId) };
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
return Ok();
}

[HttpGet]
public async Task<ActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Ok();
}
}
}

WEBページの作成

「wwwroot」フォルダーに「index.html」を作成し、

静的サイトの作成

「index.html」に次のコードをコピペします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="login">ログイン</button>
<button id="getUser">ユーザー情報取得</button>
<button id="logout">ログアウト</button>
<script>
window.onload = function() {
document.getElementById('login').onclick = function() {
login();
};
document.getElementById('getUser').onclick = function() {
getUser();
};
document.getElementById('logout').onclick = function() {
logout();
};
};

function login() {
let xhr = new XMLHttpRequest;
xhr.open('get', `/api/Account/Login?userId=abc`, true);
xhr.send();
}
function getUser() {
let xhr = new XMLHttpRequest;
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
}
};
xhr.open('get', "/api/Account/GetUser", true);
xhr.send();
}
function logout() {
let xhr = new XMLHttpRequest;
xhr.open('get', "/api/Account/Logout", true);
xhr.send();
}
</script>
</body>
</html>

Program.cs 修正

最後に「Program.cs」を修正します。

  • Cookie認証を有効化
  • APIコントローラーを有効化
  • 静的サイトを有効化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using Microsoft.AspNetCore.Authentication.Cookies;

namespace WebApplication1
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

var app = builder.Build();
if (!app.Environment.IsDevelopment()) {
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
}

これで準備完了

実行

まず、Cookieが無いことを確認します。開発者ツールの「アプリケーション」タブを開き、左ツリーから Cookie を選択すると現在の Cookie が確認できます。

この状態で「ユーザー情報取得」ボタンを押しても何も返ってきません。

Cookie認証されていないことの確認

続いて、ログインボタンを押して、Cookie認証をします。Cookie が保存されたのが分かります。

Cookie認証したCookieの確認

Cookie認証をしたあと、ユーザー情報取得ボタンを押すと、認証したユーザーIDが表示されます。

認証したユーザーIDが取得できること

最後にログアウトをすると Cookie が削除され、ユーザー情報取得もできなくなります。

おわりに

今回のソースを GitHub に置きました。

参考