フォーム認証でも、Windows認証でもなく、完全に独自の認証方法を行う場合、どのような実装を行うかのサンプルを掲載します。 シングルサインオン を実装するような ケース を想定した実装例です。 実装が web.config や Global.asax なので、ASP.NET MVC、WCF等で有効な実装方法になるハズです(試したのは ASP.NET MVC4 のみ)。
目次
ソースコード
概要
サービス へ アクセス したときの動作と、本記事の範囲外ですが前提となる動作を以下にあげます。
本記事範囲内のユースケース
- 認証されている場合(誰からのアクセスか特定できる場合)
その認証情報はあらかじめクッキーに保存してあるので、クッキー情報からHttpApplication.User
に復元します。 - 認証されていない場合(誰からのアクセスかわからない or 初回アクセスの場合)
そのまま通過させ 匿名ユーザー として処理を続行します。 - 匿名ユーザーでは許可されないアクセスの場合
http://localhost:8080/Account/Login
へリダイレクトします。
本記事範囲外のユースケース
- ユーザーを認証する
IDとパスワードでユーザーを認証し、認証したことをクライアントのクッキーに保存します。
"独自認証処理"と言いながら、実際はフォーム認証と同じことを行っています。 ただ、自前で実装しているので、拡張修正が独自に行えるかと思います。 修正が必要そうな部分を見極めて修正を行ってください。
web.config の設定
system.web/authentication
要素において、 mode="None"
を指定します。
これにより、認証処理を行わない(=自前でどうにかする)という設定になります。
認証処理はこのあとの Global.asax の実装 で記載します。
web.config
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <authentication mode="None"> </authentication> <authorization> <deny users="?"/> </authorization> </system.web> </configuration>
Global.asax の実装
ここでは「認証されている場合に特定されたユーザーを設定」「認証されていない場合に匿名ユーザーを設定」「承認されない場合にリダイレクト」の3つを実装します。 が、「認証されていない場合に匿名ユーザーを設定」は何も処理しなければ、匿名ユーザーになるので、実質的に実装が必要なのは2つです。
「認証されている場合に特定されたユーザーを設定」は、Application_AuthenticateRequest
で行います。
クッキーから復元し、設定を行います。
「承認されない場合にリダイレクト」は、Application_EndRequest
で行います。
このメソッドは、ASP.NET に対する要求処理の一番最後のイベントとして呼ばれます。
このタイミングだと、匿名ユーザーがアクセスできない場所にアクセスしたかどうか(401 Unauthorized)が分かるので、ここでリダイレクト処理を実装します。
Global.asax
namespace ServiceProvider1 { using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Mvc; using System.Web.Routing; using System.Web.Security; using System.Security.Principal; public class MvcApplication : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); } protected void Application_AuthenticateRequest(object sender, EventArgs e) { // 認証情報を格納した Cookie を取得 var authCookie = this.Request.Cookies[FormsAuthentication.FormsCookieName]; // Cookie が 存在する場合 if (authCookie != null && !string.IsNullOrEmpty(authCookie.Value)) { // Cookie から 認証情報 を復元 var ticket = FormsAuthentication.Decrypt(authCookie.Value); var identity = new GenericIdentity(ticket.Name, "Single Sing-On"); var pricinpal = new GenericPrincipal(identity, new string[] { }); HttpContext.Current.User = pricinpal; } } protected void Application_EndRequest(object sender, EventArgs e) { var url = string.Empty; // 401:Unauthorized でない場合、何もしない if (this.Response.StatusCode != 401) { return; } // リダイレクト用の URL を生成 url += "http://localhost:8080/Account/Login"; url += "?ReturnUrl="; url += HttpUtility.UrlEncode(this.Request.Url.ToString()); // リダイレクト this.Response.Redirect(url); } } }
おまけ
「リダイレクト先のサービス(http://localhost:8080)」と「本記事で作成したサービス」の web.config に 同じ machineKey
を記載すると、シングルサインオン擬き が作れます。
machineKey の生成については こちら をご参照ください。
フォーム認証ページの作成方法については こちら(ASP.NET MVC + WebAPI) か こちら(ASP.NET MVC) をご参照ください。
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!