如果您不想通过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,例如RedirectToRoute
或View
,则可以将值设置为filterContext.Result
属性。
感谢您的回复。是的,我正在努力做到这一点,以确保正确的流程。我喜欢在会话中存储完成状态并基于此设置规则。然而,正如你所提到的UrlRerrer和Seeionion ID都可以伪造,想知道有没有最好的方法来做到这一点? – matmat 2011-06-17 20:44:51
如果你不担心'手动摆弄',那么任何一种方法都可以。 – 2011-06-17 20:57:35