在我们的asp.net mvc 4项目中,我们使用AuthorizeAttribute
来实现访问控制,我们的代码就像这样
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (IsValid())
{
//do something
}
else
{
httpContext.Response.Redirect("~/Common/NoAuthorize", true);
}
}
protected bool IsValid()
{
//custom authentication logic
return true;
}
}
用Controller
标记的MVC MyAuthorizeAttribute
。问题是当用户无效时,它应该立即重定向到NoAuthorize页面。但我发现它仍将运行MVC中的代码{{ 1}}。Controller
之后就可以了。
我尝试添加Redirect
和httpContext.Response.End()
。他们都没有工作。那么如何在不运行HttpContext.Current.Response.End()
中的代码的情况下立即进行重定向?
答案 0 :(得分:2)
AuthorizeCore应该返回一个bool值。您不从该方法执行重定向。您应该从HandleUnauthorizedRequest方法
更改路径protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (IsValid())
{
return true;
}
else
{
return false;
}
}
protected bool IsValid()
{
//custom authentication logic
return true;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "ActionName" },
{ "controller", "ControllerName" }
});
}
答案 1 :(得分:0)
你可以抛出异常。
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (IsValid())
{
//do something
}
else
{
// You can throw any exception even custom.
throw new AuthenticationException("User must be logged in to access this page.");
}
}
这取决于您在应用程序中处理异常的方式。我在Global.asax.cs
中实现了以下方法。在此方法中,我检查它是否不是HttpException
,如果它是AuthenticationException
,则将其重定向到ErrorController的相应操作,在本例中为Forbidden方法。
protected void Application_Error(object sender, EventArgs e)
{
var ex = Server.GetLastError();
if (ex is HttpException)
{
var httpEx = ex as HttpException;
statusCode = httpEx.GetHttpCode();
switch (httpEx.GetHttpCode())
{
case 400:
action = "BadRequest";
break;
case 401:
action = "Unauthorized";
break;
case 403:
action = "Forbidden";
break;
case 404:
action = "PageNotFound";
break;
case 500:
action = "CustomError";
break;
default:
action = "CustomError";
break;
}
}
else if (ex is AuthenticationException)
{
action = "Forbidden";
statusCode = 403;
}
httpContext.ClearError();
httpContext.Response.Clear();
httpContext.Response.StatusCode = statusCode;
httpContext.Response.TrySkipIisCustomErrors = true;
routeData.Values["controller"] = "Error";
routeData.Values["action"] = action;
controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);
((IController) controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
}
ErrorController
Forbidden()
操作会重定向到相应的页面,如下所示:
[ExcludeFromCodeCoverage]
[AllowAnonymous]
public ActionResult Forbidden()
{
Response.StatusCode = (int)HttpStatusCode.Forbidden;
var model = (ViewData.Model as HandleErrorInfo);
string returnUrl = string.Empty;
if (model != null)
{
returnUrl = Url.Action(model.ActionName, model.ControllerName);
}
return RedirectToAction("Login", "Account", new { returnUrl = returnUrl, name = "" });
}