フォーム認証でも、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
1 2 3 4 5 6 7 8 9 10 | <? 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
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 49 50 51 52 53 54 55 56 57 58 59 60 | 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 += "?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 の フォロー」 お願いします!!