ASP.NET MVCはIrouteHandler,IHttpHandlerを利用して画像防犯チェーンを実現

7869 ワード

サーバーリクエストログに画像リソースのリクエストがたくさんあることに気づいたことがありますか?これは、彼らのウェブサイトであなたの画像を盗んだ人がいる可能性があります.これは、サーバーの帯域幅を占有します.次の方法でASPの使い方を教えてあげることができます.NET MVCでは、他の人があなたの画像を盗むのを防ぐためにカスタムRouteHandlerを実現します.
ASP.NET MVCプログラムで最初に触れる部品はUrlRoutingModuleであり、Systemである.Web.Routingの一部UrlRoutingModuleは、要求されたurlとローカルディスクのファイルが一致しているかどうかを最初に確認するために使用されます.一致する場合、UrlRoutingModuleは要求をIISに直接返信し、IISはアドレスに応じて対応します.(ここでファイルにアクセスする権限の問題があります.一般的なCSS、Html、Js、Image、またはcshtmlファイルにアクセスを要求した場合、サーバはデフォルトでその内容を返すことができます.ただし、Web.configなどのシステムキーファイルに対しては、サーバはアクセスを拒否します.)UrlRoutingModuleがディスクに一致するファイルを見つけていない場合.RouteCollection構造をチェックして、リクエストの転送を続行するかどうかを決定します.UrlRoutingModuleでは、RouteHandlerと一致するパスエントリが導入されます(デフォルトではMvcRouteHandler).その後、要求に関連する論理を処理するために適切なHttpHandlerが導入される.デフォルトでは、このHttpHandlerはMvcHandlerになります.一方、画像ファイルについては、プログラム内のあるサブディレクトリに存在することが一般的であるが、コアのrouteModuleは、画像を直接要求するurlがiisに優先的に返信するため、フローはこのときRouteHandlerに実行できない.
通常、Aspを通過する.Netディスク上の静的ファイルを取り出すことは可能です.しかし、このようなファイルを直接要求に応答させるのではなく、ビジネスロジックを実行したい場合は、いくつかのキーでプログラミングで実現する必要があります.RouteTableを設定することができますRoutes.RouteExistingFiles=trueは、既存のファイルのデフォルトの動作を回避します.Phil Haack(ASP.NET MVCの上級プログラムマネージャ)は「核兵器レベルのオプション」と呼ばれ、css、js、doc、pdfなどのファイルでも、このモードではすべてのファイルがRoutingで処理される必要があります.したがって、この点を確認する鍵は、静的ファイルの要求がディスク上の対応するファイルと一致しないことです.これにより、RouteModuleがRouteテーブルを検索するように強制されます(もちろん、RouteHandlerなどのプロシージャが導入されます).これは簡単です.要素を架空のディレクトリに向けるだけでいいです.たとえば、あなたの画像はWebサイトのルートディレクトリの下にあるimagesフォルダの下に保存されていますが、要素が「graphics」フォルダを指すと、存在するファイルと一致しません.
これを行うには、次のようにする必要があります.
画像に対する要求に対してRoute を登録する
このような要求を処理するためにRouteHandlerを作成する実際の要求を処理するためにHttpHandlerを作成するまず、RouteHandlerを作成せずにルーティングテーブルに登録するとコンパイルに成功しないため、ステップ2から開始する.
RouteHandlerは簡単でIrouteHandlerの実現であり、IHttpHandler IrouteHandlerしかない.GetHttpHandler(RequestContext requestContext):
public class ImageRouteHandler : IRouteHandler
{
  public IHttpHandler GetHttpHandler(RequestContext requestContext)
  {
    return new ImageHandler(requestContext);
  }
}

実際のHttpHandlerの場合:
public class ImageHandler : IHttpHandler
{
  public ImageHandler(RequestContext context)
  {
    ProcessRequest(context);
  }

  private static void ProcessRequest(RequestContext requestContext)
  {
    var response = requestContext.HttpContext.Response;
    var request = requestContext.HttpContext.Request;
    var server = requestContext.HttpContext.Server;
    var validRequestFile = requestContext.RouteData.Values["filename"].ToString();
    const string invalidRequestFile = "thief.gif";
    var path = server.MapPath("~/graphics/");

    response.Clear();
    response.ContentType = GetContentType(request.Url.ToString());

    if (request.ServerVariables["HTTP_REFERER"] != null &&
        request.ServerVariables["HTTP_REFERER"].Contains("mikesdotnetting.com"))
    {
      response.TransmitFile(path + validRequestFile);
    }
    else
    {
      response.TransmitFile(path + invalidRequestFile);
    }
    response.End();
  }

  private static string GetContentType(string url)
  {
    switch (Path.GetExtension(url))
    {
      case ".gif":
        return "Image/gif";
      case ".jpg":
        return "Image/jpeg";
      case ".png":
        return "Image/png";
      default:
        break;
    }
    return null;
  }

  public void ProcessRequest(HttpContext context)
  {
  }

  public bool IsReusable
  {
    get { return false; }
  }
}

 
上記のコードでは、IHttpHandlerのProcessRequestには、2つのリロードがあり、1つ目はpublic void ProcessRequest(HttpContext context)であり、ここではこのリロードを無視し、MVCプログラムでは、HttpContextオブジェクトではなくRequestContextオブジェクトをパラメータとして転送する.ProcessRequestメソッドはImageHandlerのコンストラクタで呼び出されます.上記のコードでは、ProcessRequestはまず、要求されたピクチャのアドレスが私のドメインに入力されているかどうかをチェックします(つまり、ピクチャを参照するページは他の人ではなく私のサイトです)、そうでなければ他のピクチャを返します.どのような画像を返すかはあなた自身にかかっています.私はこのような画像をたくさん見たことがあります.調和のとれない内容が含まれています.1 pxの透明gifを返すこともできるし、404 not foundを...
もちろん、この点では他のステップを取ることもできます.例えば、googleがあなたの画像をインデックスすることを望んでいるので、参照したリンクには「images」が含まれています.Google」は実際の画像を返すことができます.他のサイトでチェーンを盗んで画像が成功しない場合にログで記録することもできます.
最後のステップは、画像の要求をRouteTableに登録するために、ImageRouteHandlerがこの要求を処理することを示すために、global.axaxファイルに、以下を追加します.
routes.Add("ImagesRoute",
                 new Route("images/{filename}", new ImageRouteHandler()));