Asp.net mvc ASP.NET MVC-阻止除搜索机器人(Googlebot、Yahoo Slurp等)之外的特定控制器的所有访问者

Asp.net mvc ASP.NET MVC-阻止除搜索机器人(Googlebot、Yahoo Slurp等)之外的特定控制器的所有访问者,asp.net-mvc,Asp.net Mvc,我正在尝试为我的站点地图创建一个控制器,但只允许搜索引擎查看它 如果你看一下,你会发现他们的网站地图是。如果您尝试访问站点地图,您将被重定向到404页面 现在,我不希望这个问题以“属于元”结束,因为我只是以StackOverflow为例。我真正需要回答的是 如何阻止除搜索机器人以外的所有控制器访问者?您可能可以创建一个过滤器属性,使用用户代理标头拒绝请求。这一功能的有用性值得怀疑(并且不是一个安全功能),因为标题很容易伪造,但它将阻止人们在股票浏览器中这样做 包含googlebot使用的用户代

我正在尝试为我的站点地图创建一个控制器,但只允许搜索引擎查看它

如果你看一下,你会发现他们的网站地图是。如果您尝试访问站点地图,您将被重定向到404页面

现在,我不希望这个问题以“属于元”结束,因为我只是以StackOverflow为例。我真正需要回答的是


如何阻止除搜索机器人以外的所有控制器访问者?您可能可以创建一个过滤器属性,使用用户代理标头拒绝请求。这一功能的有用性值得怀疑(并且不是一个安全功能),因为标题很容易伪造,但它将阻止人们在股票浏览器中这样做

包含googlebot使用的用户代理字符串列表

将非Google机器人重定向到错误控制器上的404操作的示例代码:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class BotRestrictAttribute : ActionFilterAttribute {

    public override void OnActionExecuting(ActionExecutingContext c) {
      if (c.RequestContext.HttpContext.Request.UserAgent != "Googlebot/2.1 (+http://www.googlebot.com/bot.html)") {
        c.Result = RedirectToRouteResult("error", new System.Web.Routing.RouteValueDictionary(new {action = "NotFound", controller = "Error"}));
      }
    }
}
编辑以回复评论。如果站点地图存在服务器负载问题,则限制对机器人程序的访问可能是不够的。谷歌机器人本身就有能力在你的服务器决定进行攻击时使其停止运行。您可能也应该缓存响应。您可以使用相同的
filteratAttribute
Application.Cache

这是一个非常粗略的示例,可能需要调整propert HTTP头:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class BotRestrictAttribute : ActionFilterAttribute {

    public const string SitemapKey = "sitemap";

    public override void OnActionExecuting(ActionExecutingContext c) {
      if (c.RequestContext.HttpContext.Request.UserAgent != "Googlebot/2.1 (+http://www.googlebot.com/bot.html)") {
        c.Result = RedirectToRouteResult("error", new System.Web.Routing.RouteValueDictionary(new {action = "NotFound", controller = "Error"}));
        return;
      }

      var sitemap = Application.Cache[SitemapKey];
      if (sitemap != null) {
        c.Result = new ContentResult { Content = sitemap};
        c.HttpContext.Response.ContentType = "application/xml";
      }

    }
}

//In the sitemap action method
string sitemapString = GetSitemap();
HttpContext.Current.Cache.Add(
 BotRestrictAttribute.SitemapKey, //cache key
 sitemapString, //data
 null, //No dependencies
 DateTime.Now.AddMinutes(1), 
 Cache.NoSlidingExpiration, 
 CacheItemPriority.Low, 
 null //no callback
);

您可以使用的另一个方法是DNS查找,这里将对此进行解释

您可以在ViewEngine中添加反向DNA查找。

我使用的方法有点扭曲

首先,我有以下浏览器文件

SearchBot.browser

<browsers>
    <browser id="Slurp" parentID="Mozilla">
        <identification>
            <userAgent match="Slurp" />
        </identification>
        <capabilities>
            <capability name="crawler" value="true" />
        </capabilities>
    </browser>
    <browser id="Yahoo" parentID="Mozilla">
        <identification>
            <userAgent match="http\:\/\/help.yahoo.com\/help\/us\/ysearch\/slurp" />
        </identification>
        <capabilities>
            <capability name="crawler" value="true" />
        </capabilities>
    </browser>
    <browser id="Googlebot" parentID="Mozilla">
        <identification>
            <userAgent match="Googlebot" />
        </identification>
        <capabilities>
            <capability name="crawler" value="true" />
        </capabilities>
    </browser>
    <browser id="msnbot" parentID="Mozilla">
        <identification>
            <userAgent match="msnbot" />
        </identification>
        <capabilities>
            <capability name="crawler" value="true" />
        </capabilities>
    </browser>
</browsers>
最后是我的控制器

    <SearchBotFilter()> _
    Function Index() As ActionResult
        Return View()
    End Function
_
函数Index()作为ActionResult
返回视图()
端函数


感谢Igor,这是一个很好的解决方案。

我已经读到,由于欺骗,我们绝对不会使用UserAgent。我想这没什么关系,因为内容不敏感。嗯。我不确定你还能用什么来识别机器人。机器人Ip地址?某种启发式的访问分析模式?很快就会变得很棘手。让用户使用站点地图到底有什么错呢?您的方法很可能就是我将使用的方法(正如我之前所说,这不是安全需要),只是一种防止合法用户产生过多数据库负载的方法。尽管如此,我还是读了一篇关于的文章。请看下面我的答案,了解我在这方面的变化。像冠军一样工作@Igor——你问“让用户可以使用网站地图有什么不对”——我想这是双重的。1是当我的站点地图将有成千上万条记录时,会有大量的数据库负载(与此类似),2是我不希望其他web应用程序在我的站点上爬行(获取内容)。
    <SearchBotFilter()> _
    Function Index() As ActionResult
        Return View()
    End Function