プログラミング

C#でcookie認証方法

hebishima.shogo

はい、hebiです。

C#でcookie認証を使用し、WebAPIでログイン機能を作成したいと思います。.NET 6.0で作成してみました。
WebAPIの作成方法については以下を参照ください。

あわせて読みたい
C#でWeb API(Rest API)の作り方
C#でWeb API(Rest API)の作り方
スポンサーリンク

cookie認証有効設定

初めに、Programクラスにてcookie認証を有効にします。

uusing Microsoft.AspNetCore.Authentication.Cookies;

var builder = Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.SlidingExpiration = true;
        options.Events.OnRedirectToLogin = cxt =>
        {
            // ログイン画面に遷移するのではなくエラーを返す
            cxt.Response.StatusCode = StatusCodes.Status401Unauthorized;
            return Task.CompletedTask;
        };
        options.Events.OnRedirectToAccessDenied = cxt =>
        {
            // エラー画面に遷移するのではなくエラーを返す
            cxt.Response.StatusCode = StatusCodes.Status403Forbidden;
            return Task.CompletedTask;
        };
        options.Events.OnRedirectToLogout = cxt => Task.CompletedTask;
    });

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication(); // 認証を行うために追加
app.UseAuthorization();

app.MapControllers();

app.Run();

12行目のbuilder.Services.AddAuthenticationと42行目のapp.UseAuthentication()を追加しました。
(余談:.NET 6.0からMain関数が無くなり、ファイル直下に処理が書かれるようになりました。ちょっと違和感がありますがどんどん簡略化されていってます。
また、3行目のについては「Microsoft.AspNetCore.Builder.」を記述しないとビルドが通らないためお気を付けください)

ログインAPIの作成

UserControllerクラスにてログインAPIとログアウトAPIを追加します。

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using WebApplication.Midels;

namespace WebApplication.Controllers
{
    [Authorize]
    [ApiController]
    [Route("[controller]")]
    public class UserController : ControllerBase
    {
        private readonly ILogger<UserController> _logger;

        public UserController(ILogger<UserController> logger)
        {
            _logger = logger;
        }

        [AllowAnonymous]
        [HttpPost("Login")]
        public async Task<IActionResult> Login(LoginInputModel input)
        {
            // パスワード認証
            if (input.Password != "Password")
            {
                return new UnauthorizedResult();
            }

            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, input.UserName)
            };

            var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

            await HttpContext.SignInAsync(
            CookieAuthenticationDefaults.AuthenticationScheme,
            new ClaimsPrincipal(claimsIdentity));

            return Ok();
        }

        [HttpPost("Logout")]
        public async Task<IActionResult> Logout()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

            return Ok();
        }

    }
}

10行目に認証が必要であることを示す[Authorize]属性を追加します。この属性を追加することで未認証時にAPIを実行しても401エラー(Unauthorized:有効な認証資格が不足)が発生します。

22行目に認証が不要であることを示す[AllowAnonymous]属性を追加します。この属性を追加することでログインAPIは認証なしで実行することができます。

39行目で「SignInAsync」を実行し、認証処理を行います。

実行確認

デバッグ実行を行い、Swaggerを起動し、先にログアウトAPIを実行してみます。

401エラーとなり、ログアウトAPIは実行できないことが確認できました。

では、ログインAPIを実行し、200で返却されることを確認します。

その後、ログアウトAPIを実行することができました!

最後に

いかがでしたでしょうか。cookie認証を簡単に実装できたと思います。

セキュリティ面を考えると「CSRF 対策」を実装する必要があるのと、デバッグ実行するとフロントエンドとバッグエンドでポートが異なるためCORSを有効にする必要があります。
こちらについては別途記事にしたいと思います!

最後までお読みいただきありがとうございます。

追記
CORSについては以下の記事を参照ください。

あわせて読みたい
C#でCORSを有効にする方法
C#でCORSを有効にする方法
スポンサーリンク
ABOUT ME
hebi
hebi
エンジニア
フルスタックエンジニアとして活躍中。
HTML5プロフェッショナル認定Level1、Level2所持者です。

未経験の方でも簡単にプログラミングを学べるようにと情報を発信しております。
記事URLをコピーしました