httpまたはhttpsでのアクセスを強制するカスタムフィルター
httpsでしかアクセスさせたくないページの場合、そのページのアクションメソッドに
[RequireHttps]
属性を付けると、httpでアクセスしたとき自動時にhttpsにリダイレクトさせることができます。
でもその逆、httpsでアクセスしたときにhttpにリダイレクトさせるような属性は用意されていません。なので自分で作る必要があります。
これ既に作っていた人がいて、それがこちらの記事。消えちゃってるのでInternetArchiveとGistの直リンク。
- Switching between Http and Https automatically with ASP.NET MVC - Fear of a Flat Planet
- MyController.cs
このカスタムフィルター属性結構良いと思うのですが、2点おしいところがあります。
1は開発サイトとかでありがち。
その辺を考慮して少し修正した対応版作りました。
using System.Web.Mvc; namespace Utils.Filter { public enum Scheme { Ignore, Http, Https, } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class RequireHttpSchemeAttribute : FilterAttribute, IAuthorizationFilter { private readonly Scheme scheme; public RequireHttpSchemeAttribute(Scheme scheme) { this.scheme = scheme; } public void OnAuthorization(AuthorizationContext filterContext) { if ((scheme == Scheme.Https) && !filterContext.HttpContext.Request.IsSecureConnection) { filterContext.Result = GetResult(filterContext, "https://localhost:1443"); } else if ((scheme == Scheme.Http) && filterContext.HttpContext.Request.IsSecureConnection) { filterContext.Result = GetResult(filterContext, "http://localhost:1180"); } } private static RedirectResult GetResult(AuthorizationContext filterContext, string baseUrl) { var uri = new Uri(baseUrl); return new RedirectResult(uri.GetLeftPart(UriPartial.Authority) + filterContext.HttpContext.Request.RawUrl); } } }
URLベタ書きの部分は普通はWeb.config
とかに記述してあると思うからそれを使いましょう。
使い方
こんな感じです。
[RequireHttpScheme(Scheme.Http)] public virtual ActionResult HttpOnly() { return View(); }
これはhttpsでアクセスされた場合、httpにリダイレクトする。
[RequireHttpScheme(Scheme.Https)] public virtual ActionResult HttpsOnly() { return View(); }
これはhttpでアクセスされた場合、httpsにリダイレクトする。
[RequireHttpScheme(Scheme.Https)] public class AlmostSecureController : Controller { public virtual ActionResult HttpsOnly() { return View(); } [RequireHttpScheme(Scheme.Ignore)] public virtual ActionResult DoesntMatter() { return View(); } }
これはコントローラー自体に属性が付いていますので、このコントローラー内の全てのアクションメソッドでhttpsでのアクセスを強制しようとしています。しかし例外として特定のアクションメソッドにはリダイレクト処理をさせたくないという場合があります。
そういうときに例外にしたいアクションメソッドにScheme.Ignore
を設定したRequireHttpScheme
属性を付けてあげると、そのアクションメソッドでは何も起きなくなります。*4 一つのコントローラー内に沢山アクションメソッドがある場合に便利かもしれませんね。