ASP.NET Web API:Basic認証
.NET MVCのWeb APIにBasic認証を適用する方法
↑の「Web API」を選択して作成したプロジェクトを基準とする。
MSDNに凄く詳しく書いているので、基本的にはそのままに良い。
以下、自分用のメモになります。
Web.config
<system.web> ... <authentication mode="Windows" /> </system.web> <system.webServer> <modules> ... <add name="BasicAuthHttpModule" type="TestProject.Base.BasicAuthHttpModule, TestProject" /> </modules> </system.webServer>
BasicAuthHttpModule.cs
using System; using System.Linq; using System.Net.Http.Headers; using System.Security.Principal; using System.Text; using System.Threading; using System.Web; using TestProject.Base; namespace TestProject.Base { /// <summary> /// HTTP Basic 認証 /// </summary> public class BasicAuthHttpModule : IHttpModule { private const string Realm = "Test APIs"; public void Init(HttpApplication context) { // Register event handlers context.AuthenticateRequest += OnApplicationAuthenticateRequest; context.EndRequest += OnApplicationEndRequest; } private static void SetPrincipal(IPrincipal principal) { Thread.CurrentPrincipal = principal; if (HttpContext.Current != null) { HttpContext.Current.User = principal; } } private static void AuthenticateUser(string credentials) { try { var encoding = Encoding.GetEncoding("iso-8859-1"); credentials = encoding.GetString(Convert.FromBase64String(credentials)); int separator = credentials.IndexOf(':'); string username = credentials.Substring(0, separator); string password = credentials.Substring(separator + 1); // CheckPassword内でDBの値と比較するなりして認証可否を確認する if (CheckPassword(name, password)) { // 認証後の必要処理を行う var identity = new GenericIdentity(name); SetPrincipal(new GenericPrincipal(identity, null)); } else { // Invalid username or password. HttpContext.Current.Response.StatusCode = 401; } } catch (FormatException) { HttpContext.Current.Response.StatusCode = 401; } } private static void OnApplicationAuthenticateRequest(object sender, EventArgs e) { var request = HttpContext.Current.Request; var authHeader = request.Headers["Authorization"]; if (authHeader != null) { var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader); // RFC 2617 sec 1.2, "scheme" name is case-insensitive if (authHeaderVal.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase) && authHeaderVal.Parameter != null) { AuthenticateUser(authHeaderVal.Parameter); //if (!AuthenticateUser(authHeaderVal.Parameter)) //{ // HttpContext.Current.Response.StatusCode = 401; //} } } } // If the request was unauthorized, add the WWW-Authenticate header // to the response. private static void OnApplicationEndRequest(object sender, EventArgs e) { var response = HttpContext.Current.Response; if (response.StatusCode == 401) { response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", Realm)); } } public void Dispose() { } } }
TestController.cs
[Authorize] public class TestController : ApiController