检查MVC控制器权限并将401 Unauthorized返回到angularJS应用程序

时间:2016-01-08 15:00:04

标签: angularjs asp.net-mvc

我有一个angularJS应用程序,它与MVC Controller通信以获取一些数据。

我已经实现了一个继承自RBACAuthorizeAttribute的类AuthorizeAttribute,以检查用户是否有权在控制器上执行特定操作。该课程的实施如下所示:

public class RBACAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
        var webAction = filterContext.ActionDescriptor.ActionName;
        var user = filterContext.HttpContext.User.Identity.Name;


        if (!HasPermission(controllerName, webAction, user))
        {
            filterContext.Result = new RedirectToRouteResult(
                                           new RouteValueDictionary {
                                            { "action", "Index" },
                                            { "controller", "Unauthorized" } });
        }            
    }

    private bool HasPermission(string controllerName, string webAction, string user)
    {
        //Check if the user has permission here.
        //return true or false.
        return false; 
    }
}

我正在检查权限的实际控制器如下:

public class MyDataController : Controller
{
    [Route("IndividualDetails/{id}")]
    [RBACAuthorize]
    public JsonResult GetIndividualDetails(string id)
    {
        var data = GetDataFromSomeTableInDatabase(id);

        return data;
    }

UnauthorizedController类定义是:

public class UnauthorizedController : Controller
{
    public ActionResult Index()
    {
        return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
    }
} 

以下是调用控制器的AngularJS函数:

function getDetails(id) {
        return $resource(remoteServiceUrl + '/MyData/IndividualDetails/:id', { id: id })
            .get().$promise;
    };  

function loadUserDetails(id) {
    getDetails(id).then(
        function (result) {
            console.log(result);
        }, 
        function (reason) {
            console.log(reason);
        }
    );
}

我期待上面loadUserDetails函数中的 401-Unauthorized 响应,但我在result中得到了一个包含一些html页面的大数组。问题似乎出现在RBACAuthorizeAttribute类的实现中。因此,要在客户端获得 401-Unauthorized 错误,请任何人指出正确的方向。

修改: 我使用的是Asp.Net Identity系统,Asp.NET的版本是5。

2 个答案:

答案 0 :(得分:2)

  

我期待上面的401-Unauthorized响应   loadUserDetails函数但是我得到了相当大的数组   其中包含一些html页面

我认为这个HTML页面是登录页面。您可以向HttpContext添加自定义键:

calc((100% - 12px) / 3)

然后在您的Global.asax订阅public class UnauthorizedController : Controller { public ActionResult Index() { this.HttpContext.Items["SuppressAuthenticationKey"] = true; return new HttpStatusCodeResult(HttpStatusCode.Unauthorized); } } 方法并阻止重定向(如果此密钥存在):

EndRequest

如果您使用的是表单身份验证和.NET 4.5或更高版本,则可以在“未授权”操作中将SuppressFormsAuthenticationRedirect属性设置为true。

另外,我认为对protected void Application_EndRequest(object sender, EventArgs e) { var context = (HttpApplication)sender; var response = context.Response; if (context.Context.Items.Contains("SuppressAuthenticationKey")) { response.TrySkipIisCustomErrors = true; response.ClearContent(); response.StatusCode = 401; response.RedirectLocation = null; } } 行动进行额外重定向有点多余。您可以直接从自定义Unauthorized返回401:

RBACAuthorizeAttribute

答案 1 :(得分:0)

我遇到过这件事。当您返回401时,ASP.NET基础结构会将您重定向到登录页面。如果你检查从你的电话回来的字节,我愿意打赌它是你的登录页面或错误页面(如果你没有定义登录页面)。

要解决此问题,您需要修改Provider的{​​{1}}并实施自己的' OnApplyRedirect'如果它不是AJAX请求,则仅对401进行重定向的方法。

在启动代码的某个地方,你会有类似的东西:

CookieAuthenticationOptions

变量var options = new CookieAuthenticationOptions { LoginPath = new PathString(loginPath), CookieSecure = CookieSecureOption.Always, CookieName = cookieName, Provider = new CookieAuthenticationProvider() { OnApplyRedirect = context => { if (!context.Request.IsAjaxRequest()) { context.Response.Redirect(context.RedirectUri); } } } }; app.UseCookieAuthentication(options); loginPath应包含您的登录页面/操作的路径以及您的网站分别使用的Cookie的名称(例如" / Auth"和&# 34; .MySiteAuthCookie"。)

我最初在以下博客文章中给出了答案,并对我们的环境进行了一些调整。

http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes