我读过
How to easily redirect if not authenticated in MVC 3?和 Redirect to AccessDenied page when user is not authorized但是答案中的链接(表示http://wekeroad.com/2008/03/12/aspnet-mvc-securing-your-controller-actions/)不起作用。
我把
[Authorize(Users = "test")]
public class RestrictedPageController: Controller
{
public ActionResult Index()
{
return View();
}
....
}
在我的web.config中,我已经
了 <authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
相应地使用https://stackoverflow.com/a/6770583/998696
但是当我想访问/RestrictedPage/Index
时,它必须将我重定向到其他页面(来自其他控制器)。而不是这个,错误看起来像:
Server Error in '/Project' Application.
The view 'LogOn' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Account/LogOn.aspx
~/Views/Account/LogOn.ascx
~/Views/Shared/LogOn.aspx
~/Views/Shared/LogOn.ascx
~/Views/Account/LogOn.cshtml
~/Views/Account/LogOn.vbhtml
~/Views/Shared/LogOn.cshtml
~/Views/Shared/LogOn.vbhtml
登录前,Logon
页面表单正确显示,但访问/RestrictedPage/Index
页面时出现上述错误。我可以使用授权访问RestrictedPage
页面的用户登录。
我的错误在哪里以及设置重定向如何?
答案 0 :(得分:55)
默认Authorize
属性的行为方式是,当用户未经过身份验证或已经过身份验证但未经过授权时,它会将状态代码设置为< strong> 401(UnAuthorized)。当过滤器将状态代码设置为 401 时,ASP.NET框架会检查网站是否启用了表单身份验证,如果是,则重定向到那里设置的loginUrl
参数。
如果要更改该行为,则表示要将用户重定向到AccessDenied
控制器,如果用户已通过身份验证但未获得授权,则必须扩展Authorize
属性并覆盖{{ 1}}方法。
对于前。
HandleUnauthorizedRequest
您可以根据需要覆盖public class CustomAuthorize: AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new HttpUnauthorizedResult();
}
else
{
filterContext.Result = new RedirectToRouteResult(new
RouteValueDictionary(new { controller = "AccessDenied" }));
}
}
}
,然后必须标记控制器操作以使用HandleUnauthorizedRequest
属性而不是内置属性。
答案 1 :(得分:3)
我喜欢马克的答案,
但我不想改变我的所有动作属性
从[授权]到[CustomAuthorize]
我在Login()
上编辑AccountController
操作
并在显示视图之前检查Request.IsAuthenticated
我想,如果经过身份验证的用户转到/Account/Logon
,则
我将重定向到/Error/AccessDenied
。
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
if (Request.IsAuthenticated)
{
return RedirectToAction("AccessDenied", "Error");
}
ViewBag.ReturnUrl = returnUrl;
return View();
}
答案 2 :(得分:2)
放置“/ Account / LogOn”而不是“〜/ Account / LogOn”
答案 3 :(得分:1)
是的,正如您在web.config
中提到的那样<forms loginUrl="~/Account/LogOn" timeout="2880" />
重定向正在寻找Account控制器和LogOn actionresult。如果您想重定向您的网页,请更改该网页而不是帐户和登录
答案 4 :(得分:1)
由于我不想覆盖AuthorizeAttribute
我使用了过滤器
public class RedirectFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!IsAuthorized(filterContext))
{
filterContext.Result =
new RedirectToRouteResult(new RouteValueDictionary(new {controller = "AccessDenied"}));
}
}
private bool IsAuthorized(ActionExecutingContext filterContext)
{
var descriptor = filterContext.ActionDescriptor;
var authorizeAttr = descriptor.GetCustomAttributes(typeof(AuthorizeAttribute), false).FirstOrDefault() as AuthorizeAttribute;
if (authorizeAttr != null)
{
if(!authorizeAttr.Users.Contains(filterContext.HttpContext.User.ToString()))
return false;
}
return true;
}
}