Guy*_*Guy 73 c# asp.net-mvc redirect authorization
我在ASP.NET MVC中有一个控制器,我已将其限制为admin角色:
[Authorize(Roles = "Admin")]
public class TestController : Controller
{
...
Run Code Online (Sandbox Code Playgroud)
如果不在Admin角色中的用户导航到此控制器,则会显示空白屏幕.
我想要做的是将它们重定向到View,其中显示"您需要处于Admin角色才能访问此资源".
我想到的一种方法是在IsUserInRole()上检查每个操作方法,如果不在角色中,则返回此信息视图.但是,我必须在每个打破DRY主体的Action中加入它,显然很难维护.
tva*_*son 69
基于AuthorizeAttribute创建自定义授权属性并覆盖OnAuthorization以执行检查完成的方式.通常,如果授权检查失败,AuthorizeAttribute会将过滤结果设置为HttpUnauthorizedResult.您可以将其设置为ViewResult(Error视图).
编辑:我有一些博客文章更详细:
例:
[AttributeUsage( AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false )]
public class MasterEventAuthorizationAttribute : AuthorizeAttribute
{
/// <summary>
/// The name of the master page or view to use when rendering the view on authorization failure. Default
/// is null, indicating to use the master page of the specified view.
/// </summary>
public virtual string MasterName { get; set; }
/// <summary>
/// The name of the view to render on authorization failure. Default is "Error".
/// </summary>
public virtual string ViewName { get; set; }
public MasterEventAuthorizationAttribute()
: base()
{
this.ViewName = "Error";
}
protected void CacheValidateHandler( HttpContext context, object data, ref HttpValidationStatus validationStatus )
{
validationStatus = OnCacheAuthorization( new HttpContextWrapper( context ) );
}
public override void OnAuthorization( AuthorizationContext filterContext )
{
if (filterContext == null)
{
throw new ArgumentNullException( "filterContext" );
}
if (AuthorizeCore( filterContext.HttpContext ))
{
SetCachePolicy( filterContext );
}
else if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
// auth failed, redirect to login page
filterContext.Result = new HttpUnauthorizedResult();
}
else if (filterContext.HttpContext.User.IsInRole( "SuperUser" ))
{
// is authenticated and is in the SuperUser role
SetCachePolicy( filterContext );
}
else
{
ViewDataDictionary viewData = new ViewDataDictionary();
viewData.Add( "Message", "You do not have sufficient privileges for this operation." );
filterContext.Result = new ViewResult { MasterName = this.MasterName, ViewName = this.ViewName, ViewData = viewData };
}
}
protected void SetCachePolicy( AuthorizationContext filterContext )
{
// ** IMPORTANT **
// Since we're performing authorization at the action level, the authorization code runs
// after the output caching module. In the worst case this could allow an authorized user
// to cause the page to be cached, then an unauthorized user would later be served the
// cached page. We work around this by telling proxies not to cache the sensitive page,
// then we hook our custom authorization code into the caching mechanism so that we have
// the final say on whether a page should be served from the cache.
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge( new TimeSpan( 0 ) );
cachePolicy.AddValidationCallback( CacheValidateHandler, null /* data */);
}
}
Run Code Online (Sandbox Code Playgroud)
Len*_*rri 26
您可以HandleUnauthorizedRequest在自定义内部使用可覆盖的内容AuthorizeAttribute
像这样:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// Returns HTTP 401 by default - see HttpUnauthorizedResult.cs.
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "YourActionName" },
{ "controller", "YourControllerName" },
{ "parameterName", "YourParameterValue" }
});
}
Run Code Online (Sandbox Code Playgroud)
你也可以这样做:
private class RedirectController : Controller
{
public ActionResult RedirectToSomewhere()
{
return RedirectToAction("Action", "Controller");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以通过HandleUnauthorizedRequest以下方式在方法中使用它:
filterContext.Result = (new RedirectController()).RedirectToSomewhere();
Run Code Online (Sandbox Code Playgroud)
小智 10
"tvanfosson"的代码给了我"执行子请求时出错"..我已经改变了OnAuthorization,如下所示:
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (!_isAuthorized)
{
filterContext.Result = new HttpUnauthorizedResult();
}
else if (filterContext.HttpContext.User.IsInRole("Administrator") || filterContext.HttpContext.User.IsInRole("User") || filterContext.HttpContext.User.IsInRole("Manager"))
{
// is authenticated and is in one of the roles
SetCachePolicy(filterContext);
}
else
{
filterContext.Controller.TempData.Add("RedirectReason", "You are not authorized to access this page.");
filterContext.Result = new RedirectResult("~/Error");
}
}
Run Code Online (Sandbox Code Playgroud)
这很好用,我在错误页面上显示TempData.感谢代码片段的"tvanfosson".我正在使用Windows身份验证,_isAuthorized只是HttpContext.User.Identity.IsAuthenticated ...
我遇到过同样的问题.我没有找出MVC代码,而是选择了一个看似有效的廉价黑客.在我的Global.asax类中:
member x.Application_EndRequest() =
if x.Response.StatusCode = 401 then
let redir = "?redirectUrl=" + Uri.EscapeDataString x.Request.Url.PathAndQuery
if x.Request.Url.LocalPath.ToLowerInvariant().Contains("admin") then
x.Response.Redirect("/Login/Admin/" + redir)
else
x.Response.Redirect("/Login/Login/" + redir)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
104371 次 |
| 最近记录: |