我有一个MVC网站,其中访问基于各种角色。一旦用户登录系统,他们就可以看到导航到他们被授权的页面。但是,某些用户可能仍尝试使用直接URL访问页面。如果是这样,系统会自动将它们重定向到登录页面。而不是登录页面我想将它们重定向到另一个视图(未经授权)。
Web.Config有以下条目:
<customErrors mode="On">
<error statusCode="401" redirect="~/Home/Unauthorized" />
<error statusCode="404" redirect="~/Home/PageNotFound" />
</customErrors>
<authentication mode="Forms">
<forms name="Development" loginUrl="~/Account/Login" cookieless="UseCookies" timeout="120"></forms>
</authentication>
我也在Global.asax.cs中注册了这些路线。
routes.MapRoute(
name: "Unauthorized",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Unauthorized", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "PageNotFound",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "PageNotFound", id = UrlParameter.Optional }
);
这还够吗?
答案 0 :(得分:23)
经过一番研究后,我认为这个问题最简单的答案就是创建自定义授权,非常类似于jbbi的那个(但是自从&#34;新的HttpUnauthorizedResult()&#34以来,它没有工作。 ;是internaly自动重定向到登录 - 至少在mvc 5中具有标识)
public class CustomAuthorize : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
//if not logged, it will work as normal Authorize and redirect to the Login
base.HandleUnauthorizedRequest(filterContext);
}
else
{
//logged and wihout the role to access it - redirect to the custom controller action
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "AccessDenied" }));
}
}
}
,其用法与默认授权:
相同[CustomAuthorize(Roles = "Administrator")]
然后,只是为了做正确的事情,不要忘记发送错误页面的Http代码。 F.E.在控制器中这样。
public ActionResult AccessDenied()
{
Response.StatusCode = 403;
return View();
}
这很简单,有效,甚至我(.net mvc rookie)也明白这一点。
注意:它与401代码的工作方式不同 - 它将始终接管401并将internaly重定向到登录。但就我而言,根据定义,403也适合。
答案 1 :(得分:16)
通过以下更改,它正在运作
public class CustomAuthorize : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//filterContext.Result = new HttpUnauthorizedResult(); // Try this but i'm not sure
filterContext.Result = new RedirectResult("~/Home/Unauthorized");
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (this.AuthorizeCore(filterContext.HttpContext))
{
base.OnAuthorization(filterContext);
}
else
{
this.HandleUnauthorizedRequest(filterContext);
}
}
}
然后在Controller或Action上应用如下:
[CustomAuthorize(Roles = "Admin")]
通过上述方法,我需要重新访问所有控制器/操作并更改授权属性!此外,还需要进行一些测试。
我仍然不确定为什么在MVC文档中解释了为什么Web.Config路由不能正常工作。可能是MVC 4中发生了变化!
答案 2 :(得分:4)
处理此问题的最佳方法可能是创建一个额外的操作过滤器,如果用户不属于指定的角色,则会将用户重定向到指定的错误页面。 因此,此方法将应用两个过滤器:[授权](没有角色)来保护未经身份验证的用户并将其重定向到登录页面。以及具有角色的自定义属性。代码SIMILAR(未经测试):
public class RoleFilterAttribute : ActionFilterAttribute
{
public string Role { get; set; }
public override void OnActionExecuting(ActionExecutingContext ctx)
{
// Assume that we have user identity because Authorize is also
// applied
var user = ctx.HttpContext.User;
if (!user.IsInRole(Role))
{
ctx.Result = new RedirectResult("url_needed_here");
}
}
}
将[Authorize]和[RoleFilter]同时应用于操作...
希望这有帮助!
答案 3 :(得分:2)
我认为您应该创建自己的授权过滤器属性,该属性继承默认的授权过滤器
public class CustomAuthorize: AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new HttpUnauthorizedResult(); // Try this but i'm not sure
}
}
答案 4 :(得分:0)
要重定向未经授权的页面访问Asp.net C#到自定义视图
protected void Page_Load(object sender, EventArgs e)
{
try
{
txtUsername.Focus();
if (!IsPostBack)
{
if (Request.IsAuthenticated && !string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))
{
Response.Redirect("UnauthorizedAccess.aspx", false);
return;
}
Session.Clear();
Session.Abandon();
}
}
catch (Exception ex)
{
this.errLogin.Text = ex.Message;
}
}
2)创建UnauthorizedAccess.aspx
<h1>Unauthorized</h1>
<p>Sorry, you are not authorized to access this page</p>
<asp:LinkButton ID="lnkhome" runat="server" CssClass="btn btn-success1" OnClick="lnkhome_Click"
CausesValidation="false"><span class="fa fa-home"/> Back to Home</asp:LinkButton>