ASP.Net MVC:检查URL是否已授权

时间:2011-06-25 20:32:39

标签: asp.net-mvc controller authorization roles routes

我想简单地从控制器检查是否有其他URL被授权。

所以,例如,我想像这样调用一个控制器:

[HttpPost]
public ActionResult IsUrlAuthorized(string url)
{
    bool isAuthorized = // What do I put here?
    return Json(isAuthorized);
}

所以我想知道我可以调用什么来检查当前用户是否有权使用传入的URL。我猜这个答案与Routes有什么关系,它稍微偏离了MVC?

这是一个有点类似的问题,但不完全相同: ASP.NET MVC. Check if user is authorized from JavaScript

由于用户可能会或可能不会获得授权,但可能没有正确的权限或角色分配来查看特定的网址。

想法?

更新:我使用标准的MVC授权属性来锁定我的应用程序,因此我将举一个例子来说明这里的内容。在MVC路由中映射到控制器。 Controller上的单个方法可以限制为一个或多个角色:

public class HomeController : Controller
{
    [Authorize(Roles = "User, Moderator")]
    public ActionResult ListRecentPosts()
    {
        . . .
    }
}

或者,整个Controller可以限制为一个或多个角色:

[Authorize(Roles = "Admin")]
public class AdminController : Controller
. . .

任何这些控制器方法响应的实际URL都基于标准MVC应用程序中的默认映射:

routes.MapRoute("Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

但是,通过添加更多路由,您可以对用户很好并使URL可猜测 - 因此,Controller方法可以有许多指向它的名称。您不能只假设并推断URL中的控制器名称(即使它以这种方式为站点中的一半URL映射)。

所以我可能需要一种方法直接向路由引擎询问是否为当前用户授权URL,或者向路由引擎询问哪个控制器和方法的两步,然后询问这些是否被授权 - 希望不是直接使用反射和匹配角色,因为它似乎再次假设过多。

更新2:出现这种情况的方法是我的应用程序顶部有一个帐户条。通过选择您被授权的多个帐户之一,可以更改其状态。根据您在应用中的位置,您选择的帐户可能有权查看此页面 - 您可能正在填写您不想丢失的表单。因此,天真的方法 - 只是在他们选择另一个帐户时刷新 - 是有害的,即使没有形式也浪费用户的时间,他们只是阅读一个全文的页面。

虽然对用户的这种便利性很好,但是用户会公平地认为他们看不到作为不应该获得许可的用户的页面确实被拒绝了(并且将它们留在被禁止的页面 - 从中​​获取的操作将失败)。因此,我需要知道是否根据新的权限重定向。

我喜欢的东西之一.Net是许多最好的库分解得如此之好的方式,因此你可以轻松地重新组合其正常功能或新功能的一部分。路由模块和MVC看起来构造得非常好,所以我不得不怀疑这可以做到。

便宜的黑客攻击是确保我的授权模块在未授权用户时返回一致的重定向状态代码,当用户在帐户条中更改其帐户时,触发2个AJAX调用:一个用于更改帐户,以及那么通过AJAX的当前页面只需检查HTTP状态代码。 200 OK表示保持页面不变,重定向表示遵循重定向。显然这有点难看,涉及额外的HTTP调用,在日志中创建错误命中,并假设如何在整个应用程序中处理授权。

可能存在次要问题 - 页面可能已获得授权,但只是更改其工作方式或外观。这个特定的应用程序在基于帐户的外观上没有变化(除了帐户条本身),我可以通过提供形式监听的自定义事件来处理功能更改 - 他们可以从服务器重新加载任何相关数据以响应它。

2 个答案:

答案 0 :(得分:4)

只有在您使用URL授权时,才能使用UrlAuthorization.CheckUrlAccessForPrincipal。但对于使用路由的MVC,我们强烈建议您不要使用URL授权来保护应用程序。

相反,我们建议在控制器类上使用Authorization属性。原因是可能有多个URL调用相同的控制器操作。最好是在资源上保护资源,而不仅仅是在入口处。

在这种特殊情况下,您必须获取给定URL的控制器实例。这有点棘手,因为您基本上必须运行MVC管道,从您拥有URL的位置到您拥有控制器的位置。这是可能的,但似乎是重量级的。

我想知道是否有更好更简单的方法来实现你的目标。你真的想做什么?

更新:根据您的情况,听起来这只是用于UI目的的初始检查。也许您需要做的就是对URL发出异步Ajax请求并检查HTTP状态代码。如果它是401状态代码,则表示用户未获得授权。这似乎是最安全的赌注。

答案 1 :(得分:-1)

UrlAuthorizationModule.CheckUrlAccessForPrincipal方法怎么样。

UrlAuthorizationModule.CheckUrlAccessForPrincipal Method (System.Web.Security)