检查MVC控制器权限并将401未经授权返回angularJS应用程序
我有一个angularJS应用程序,它与MVC控制器通信以获取一些数据 我实现了一个类检查MVC控制器权限并将401未经授权返回angularJS应用程序,angularjs,asp.net-mvc,Angularjs,Asp.net Mvc,我有一个angularJS应用程序,它与MVC控制器通信以获取一些数据 我实现了一个类RBACAuthorizeAttribute,该类继承自AuthorizeAttribute,用于检查用户是否有权在控制器上执行特定操作。该类的实现如下所示: public class RBACAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filter
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;
}
未经授权的控制器
类定义为:
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响应,但是我在结果中得到了一个相当大的数组,其中包含一些html页面。问题似乎出现在RBACAuthorizeAttribute
类的实现中。因此,要在客户端获得401未经授权的错误,请任何人告诉我正确的方向
编辑:
我使用的是Asp.Net身份识别系统,Asp.Net的版本是5
我期待着上面的401未经授权的响应
loadUserDetails函数,但我得到了一个相当大的数组
其中包含一些html页面
我假设这个HTML页面是登录页面。您可以向HttpContext添加自定义密钥:
public class UnauthorizedController : Controller
{
public ActionResult Index()
{
this.HttpContext.Items["SuppressAuthenticationKey"] = true;
return new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
}
}
然后在您的Global.asax中订阅EndRequest
方法,并在存在此密钥时阻止重定向:
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;
}
}
如果您使用的是Forms身份验证和.NET 4.5或更高版本,则可以在未经授权的操作中将该属性设置为true
另外,我认为对您的未经授权的操作进行额外重定向是多余的。您可以直接从自定义的RBACAuthorizeAttribute
返回401:
filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
我碰到过这件事。当您返回401时,ASP.NET基础结构会将您重定向到登录页面。如果您检查从您的呼叫返回的字节,我愿意打赌它是您的登录页面或错误页面(如果您没有定义登录页面)
要解决这个问题,您需要为您的CookieAuthenticationOptions
修改提供程序
,并实现您自己的“OnApplyRedirect”方法,仅在401上执行重定向(如果它不是AJAX请求)
在启动代码中的某个地方,您将有如下内容:
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
和cookieName
应分别包含登录页面/操作的路径和站点使用的cookie名称(例如“/Auth”和“.MySiteAuthCookie”)
我最初在下面的博文中给出了答案,并根据我们的环境对其进行了一些调整
您是否使用表单身份验证?还有哪个版本的ASP.NET?这就是答案。感谢您的及时回复。它可以工作,但对于使用ASP.NET标识的应用程序来说,它不是标准解决方案。