ASP.NET Core で Basic 認証を行うサンプルを書いてみた。ユーザーは固定なので、本番で使うときは ASP.NET Core Identity みたいに、ユーザー情報をストアから取得するようにしたほうがいいだろうな。
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; using System.IO; using System.Security.Claims; using System.Text; using System.Threading.Tasks; namespace BasicAuthExample { // Basic 認証ミドルウェア public class BasicAuthenticationMiddleware { const string USER_NAME = "tnakamura"; const string PASSWORD = "test12345"; readonly RequestDelegate _next; public BasicAuthenticationMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { // Basic 認証のヘッダー // Authorization: Basic <userName:password を Base64 エンコードした文字列> // からユーザー名とパスワードを取り出してチェックする string header = context.Request.Headers["Authorization"]; if (header != null && header.StartsWith("Basic")) { var encodedCredentials = header.Substring("Basic".Length).Trim(); var credentials = Encoding.UTF8.GetString(Convert.FromBase64String(encodedCredentials)); var separatorIndex = credentials.IndexOf(':'); var userName = credentials.Substring(0, separatorIndex); var password = credentials.Substring(separatorIndex + 1); if (userName == USER_NAME && password == PASSWORD) { // コンテキストにユーザー情報をセットする var claims = new[] { new Claim(ClaimTypes.Name, userName), new Claim(ClaimTypes.Role, "User") }; var identity = new ClaimsIdentity(claims, "Basic"); context.User = new ClaimsPrincipal(identity); await _next(context); return; } } // ブラウザの認証ダイアログを出すには、レスポンスヘッダーに // WWW-Authenticate: Baic が必要 context.Response.Headers["WWW-Authenticate"] = "Basic"; context.Response.StatusCode = 401; } } public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMiddleware<BasicAuthenticationMiddleware>(); app.Run(async (context) => { await context.Response.WriteAsync($"Hello {context.User.Identity.Name}!"); }); } } public class Program { public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); } } }