ASP.Net MVC中的会话修复

时间:2009-11-02 19:45:34

标签: asp.net-mvc security routes

是否可以阻止直接从浏览器执行的操作,但仍然可以从站点内部重定向到该操作?我知道这听起来很愚蠢,但这就是我想要的:

假设Index有两条路线Index2HomeController

www.website.com/home将导致执行索引,然后我想执行一些代码然后重定向(或服务器传输)到www.website.com/home/index2

我不希望用户直接访问网址www.website.com/home/index2,而不首先转到home/index

我可以做些什么来在运行时停用/激活路线?

编辑:抱歉,这个问题标题为“会话修复”,因为我需要在Index之前运行Index2,以确保我们在Index中删除所有会话并在Index2之前续订{1}}执行。

我无法终止会话并在同一请求中执行Index2中的代码,因为Index2需要会话来完成其工作。

5 个答案:

答案 0 :(得分:3)

如果您进行重定向,则不会。如果你进行重定向,它将在控制器中显示,就像请求只是源自浏览器一样(它确实如此)。你可以使用TempData来解决问题 - 即在那里设置一个标志,只有当标志位于TempData时才执行操作 - 但如果它不是来自浏览器的下一个请求,它将失败。也就是说,您可能会收到另一个请求,例如通过AJAX,来自原始和重定向之间。 TempData将被该请求消灭。

另一方面,如果您只想执行代码,则不要将Index2公开为公共方法并直接调用它。如果它在同一个控制器中,这应该可行。你最终会得到相同的网址,但是如果它只是获得你想要的正确视图,那么这应该没问题。

答案 1 :(得分:1)

如果用户被重定向到www.website.com/home/index2,那么他们必须提出浏览器请求,即使它是代表他们自动发生的。防止这种情况的唯一方法是检查检查HTTP Referer的Index2操作。

另一个选择是让Index返回Index2的ActionResult,这样URL保留在/ home / index,但返回Index2的结果,就用户而言,它们从未被重定向。

答案 2 :(得分:1)

您可以放置​​一个ActionFilter并从那里进行会话清理。这样,您的代码将始终在Index2之前执行 - 并且在您放置此属性的任何操作之前执行。

public class AbandonSessionAttribute: ActionFilterAttribute
{
   public void OnActionExecuting(ActionFilterContext context)
   {
      if (Session.User.IsAuthenticated || Session.Count > 0)   // <<-- this is the important line
      {
         Session.Clear();
         FormsAuthentication.SignOut(); // and so on
         context.Result = new RedirectResult("/Index2");
      }
   }
}

// now, if this is called with non-empty session, it will be cleared and user will be redirected again here
[AbandonSession]
public ActionResult Index2()
{
}

请注意“这是重要的一行”。在那里,您需要检测是否允许用户输入Index2。我通过检查Session不为空来做到这一点。但是,在重定向MVC之后可能会添加它自己的Session变量,因此Session不会为空,并且过滤器将一次又一次地重定向......您需要找出可以在Session中显示的内容。根据您的问题,(对我来说) ANY 导航到Index2是否应该清除会话(即在网站浏览期间)并不清楚。如果是这样,上面的代码就可以了,如果没有 - 由你来决定如何检测这个(例如,在某些页面上将某些内容放入会话中并在其他页面上删除)。

同样,我不明白为什么Session不适合你(以及TempData 通过Session工作的方式)。如果您检测到该请求的操作过滤器不是“干净” - 那么就是登录,会话变量等 - 所以你要清理它并再次重定向到同一个动作 - 这会导致新的会话创建和等等。这次过滤器找不到任何东西 - 因为会话刚刚被清理 - 因此允许执行操作。

答案 3 :(得分:1)

好的,这就是我们最终做的事情。有人用这种方法看到任何警告吗?

Index()
{
    expire all session and forms-Authententication cookies
}

Index2()
{
   if(Session.IsNewSession)
   {
      redirect to Index action
   } 
   else
   {
     Show view
   }
}

答案 4 :(得分:0)

您可以定义路由:

routes.MapRoute(
            "Index2Redirect",
            "HomeController/Index2",
            new { controller = "HomeController", action = "Index", id = "" }
        );

修改

不,这不好。