2011-06-17 61 views
0

我有一个遵循PRG模式的MVC3应用程序,我正在寻找一种定义导航规则到我的应用程序的最佳方式。例如,我有页面A,B,C和D的应用程序。让我们说A是一个登录页面。用户登录成功后,用户将被重定向到页面B.现在我不想让用户在地址栏中键入页面C的URL并访问页面C(页面C应该只能在POST页面B后访问或从页面D后退按钮)我必须为所有其他页面设置类似的规则(可以说当用户在页面D,不应该让他们进入页面B)MVC 3页面导航安全规则

目前我有一个选项,我可以在哪里检查@ Request.UrlRefferer属性以获取每个请求的来源并决定将哪个页面重定向到。我不确定这是一个最佳解决方案。

感谢您的反馈!

回答

0

我结束了如下完成这个任务:

  1. 在每一页的顺利完成,保存页面名称数据库
  2. 当一个新的页面用户请求时,只需按一下网页,他们已经完成最后来自数据库并决定要做什么。

我选择这种方法简单,因为它会解决问题过程中绝对帮助/故障排除一次应用是在生产,这是巨大的我。

感谢大家的回复!

1

不要将您的安全建立在此基础之上。使用[授权]属性来定义安全性。 UrlReferrer也很容易伪造。

你为什么想限制这个?如果你有一个商业原因,用户最为经过一个特定的流量,然后再考虑任何一个cookie,会话或数据库条目要注意他们当前的“完成”状态 - IE一些稍微持久的方法来确定这一点。你也可以根据说 - 会话ID - 形成一个令牌传递到每个页面。如果令牌存在并与用户的当前会话相匹配,则为其加载页面。当然,如果用户理解这一点,这可能是伪造的 - 但如果你只是试图确保正确的流程,那么这也是一种方法。用户不会获得与当前会话ID的链接,直到他们达到上一步。

+0

感谢您的回复。是的,我正在努力做到这一点,以确保正确的流程。我喜欢在会话中存储完成状态并基于此设置规则。然而,正如你所提到的UrlRerrer和Seeionion ID都可以伪造,想知道有没有最好的方法来做到这一点? – matmat 2011-06-17 20:44:51

+0

如果你不担心'手动摆弄',那么任何一种方法都可以。 – 2011-06-17 20:57:35

1

如果您不想通过URL访问特定页面,则可用的一个选项是确保无法通过URL访问该页面。要访问该页面,请执行POST操作,该操作将返回视图而不是重定向。这意味着您的POST操作返回的视图将显示在包含上一页的URL的页面上。对于exameple:

页面的URL是/login,并登录后,用户会被重定向到页面B.现在/home的网址。页面B发送POST请求,页面内容变为页面C,但URL仍然保留为/home。查看页面C内容的唯一方法是访问页面B并发送POST请求。

这打破了PRG模式,但这是一种选择。

还有一个选择,存储用户的当前权限,指明他们允许进入哪个页面,并检查用户是否有权在执行操作之前查看页面。您可以将代码放在ActionAttribute中,您可以将其应用于您的操作方法或整个控制器。如果您想要更详细地解释这种技术,请留下我的评论,然后我会更详细地写出另一个描述此技术的答案。


这里的上述技术的快速验证的概念:

public class PermissionsNeeded : ActionFilterAttribute 
{ 
    string expectedPermission; 

    public PermissionsNeeded(string permission) 
    { 
     expectedPermission = permission; 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     var currentPermissions = filterContext.HttpContext.Session["CurrentPermissions"] as IEnumerable<string> ?? new List<string>(); 

     // If user does NOT have permission to access the action method 
     if(!currentPermissions.Contains(expectedPermission) 
     { 
      throw new HttpException(403, "User is not authorized to view this page"); 
     } 
    } 
} 

class YourController : Controller 
{ 
    [HttpPost] 
    public ActionResult PageB() 
    { 
     var currentPermissions = Session["CurrentPermissions"] ?? new List<string>(); 
     currentPermissions.Add("PostedFromPageB"); 
     Session["CurrentPermissions"] = currentPermissions; 

     return RedirectToAction("PageC"); 
    } 

    [PermissionsNeeded("PostedFromPageB") 
    public ActionResult PageC() 
    { 
     return View(); 
    } 
} 

目前,自定义属性只会在时间,这是一个简单的限制,纠正接受一个许可。当您觉得用户不再有某些权限时,您将负责删除存储在会话中的权限。我抛出了一个返回403状态码(未经授权的访问)的HttpException,但是如果您希望返回ActionResult,例如RedirectToRouteView,则可以将值设置为filterContext.Result属性。

+0

感谢您的回复。我不喜欢打破PRG模式。你能解释你的其他选择吗? – matmat 2011-06-17 20:33:19

+0

@matmat:为我之前描述的替代方法添加了一个概念验证。可能需要进行一些更改以使其完全符合您的需求。如果您需要任何澄清,请告诉我。 – xTRUMANx 2011-06-18 06:39:28

+0

感谢您的回应,尽管您的方法是一种选择,但我决定使用数据库,因为它有助于排除故障。请参阅下面的答案。 – matmat 2011-06-20 01:39:56