2011-06-25 42 views
3

我想简单地从一个控制器中的另一个URL是否被授权检查。ASP.Net MVC:检查URL被授权

因此,例如,我想打电话到控制器中,像这样:

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

所以我想知道我可以打电话来检查当前用户是否被授权传递是否在URL中。我猜测答案与路线有关,MVC之外有一些位置?

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

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

想法?

更新:我使用标准的MVC授权属性来锁定我的应用程序,所以我就放弃的东西,看起来像这里的例子。在MVC路线中映射到控制器。上的控制器的单个方法可以被限制为一个或多个角色:

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

或者,整个控制器可以被限制为一个或多个角色:

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

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

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

但是,你可以对用户友好,并加入了更多的途径让网址猜测的 - 作为AR一个Controller方法可以有许多指向它的名字。您不能仅仅假设并从URL推断出控制器名称(即使它以这种方式映射网站中一半的URL)。

所以大概我需要一种方法来直接询问路由引擎是否授权给当前用户的URL,或者是询问路由引擎的哪个控制器和方法的两个步骤,然后询问是否授权 - 希望不要直接使用Reflection和匹配角色,因为这会再次假设太多。

更新2:此想出的方法是我有一个帐户带在我的应用程序的顶部。其状态可以通过选择您授权的几个帐户之一进行更改。根据您在应用程序中的位置,您选择的帐户可能有权查看此页面 - 而且您可能正在填写您不想丢失的表单。所以,天真的方法 - 当他们选择其他帐户只刷新 - 是有害的,并且用户的浪费时间,即使是没有形式和他们只是在阅读页面的所有文本。

尽管对用户的便利性很好,但用户会公平地认为他们无法看到的不应该拥有权限的用户的页面确实遭到拒绝(并且,将它们留在一个被禁止的页面 - 从它取得的行动将失败)。所以我需要知道是否根据他们的新权限重定向。

一个我喜欢的.Net的事情就是这样,它的许多最好的图书馆分解这么好,所以你可以很容易地重构的东西,是其正常功能的一部分,或者一个新的转折。路由模块和MVC似乎构建得非常好,所以我不得不怀疑这可以完成。

廉价黑客是为了确保我的授权模块在用户未被授权时返回一致的重定向状态码,以及当用户在帐户条中更改其帐户时,激发2个AJAX呼叫:一个更改帐户,然后通过AJAX第二个到当前页面来检查HTTP状态码。 200 OK表示按原样离开页面,重定向表示按照重定向。显然,这有点难看,需要额外的HTTP调用,在日志中创建一个错误命中,并假设如何在整个应用程序中处理授权。

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

+0

这些正确的权限在哪里存储 – Tassadaque

+0

我将扩展我的问题给出我当前如何定义权限的示例(它是标准的MVC的东西) –

回答

4

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

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

在这种特殊情况下,您必须获得给定URL的控制器实例。这有点棘手,因为你基本上必须从拥有URL的地方运行MVC流水线到拥有控制器的点。这是可能的,但似乎重量级。

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

更新:根据你的情况,这听起来像这是一个初始检查只是为了UI的目的。也许你需要做的只是向URL发出异步Ajax请求并检查HTTP状态码。如果它是401状态码,则知道该用户未被授权。这似乎是最安全的赌注。

+0

我会更多地解释这个问题来解释目标。 –

-1

如何UrlAuthorizationModule.CheckUrlAccessForPrincipal方法。

UrlAuthorizationModule.CheckUrlAccessForPrincipal Method (System.Web.Security)

+0

从来没有尝试过,但它会在授权不骑典型的ASP.NET映射到文件funk-schwa,但是需要计算路由并找出哪个控制器和动作在起作用? –

+0

创建默认的mvc3解决方案,以及Home/Index.cshtml编写@ UrlAuthorizationModule.CheckUrlAccessForPrincipal(“〜/ Account/ChangePassword”,User,“GET”)。allways true!嗯,对不起,不工作。 – takepara

+0

UrlAuthorizationModule.CheckUrlAccessForPrincipal未检查授权属性... – takepara