Ron*_*rby 45 .net c# asp.net asp.net-mvc authorization
在我的ASP.NET MVC应用程序中,我有大多数控制器装饰
[Authorize(Roles="SomeGroup")]
Run Code Online (Sandbox Code Playgroud)
当用户无权访问某些内容时,会将其发送到"〜/ Login",这是我的帐户控制器上的"登录"操作.
如何确定用户因未获得授权而已到达登录页面,以便我能够显示相应的错误?
Ben*_*ull 76
更新(2015年6月): @ daniel-lidström已正确指出您不应在ASP.NET MVC应用程序中使用Response.Redirect.有关原因的更多信息,请参阅此链接:Response.Redirect和ASP.NET MVC - 不要混合.
更新(2014年9月):我不确定何时将HandleUnauthorizedRequest添加到AuthorizeAttribute,但无论哪种方式,我都能够将AuthorizeRedirect代码细化为更小更简单的代码.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeRedirect : AuthorizeAttribute
{
public string RedirectUrl = "~/Error/Unauthorized";
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult(RedirectUrl);
}
}
}
Run Code Online (Sandbox Code Playgroud)
原始答案如下(仍然功能齐全)
我在这里留下了这个答案,因为它仍然让您了解授权管道的工作原理.
对于仍然登陆这里的人,我编辑了Ben Scheirman的答案,当用户登录但未授权时自动重定向到未经授权的页面.您可以使用名称参数RedirectUrl更改重定向路径.
编辑:由于Tarynn和MSDN的建议,我已经使解决方案线程安全
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeRedirect : AuthorizeAttribute
{
private const string IS_AUTHORIZED = "isAuthorized";
public string RedirectUrl = "~/error/unauthorized";
protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
{
bool isAuthorized = base.AuthorizeCore(httpContext);
httpContext.Items.Add(IS_AUTHORIZED, isAuthorized);
return isAuthorized;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
var isAuthorized = filterContext.HttpContext.Items[IS_AUTHORIZED] != null
? Convert.ToBoolean(filterContext.HttpContext.Items[IS_AUTHORIZED])
: false;
if (!isAuthorized && filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.RequestContext.HttpContext.Response.Redirect(RedirectUrl);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Ben*_*man 28
您可以查找?ReturnUrl= 查询字符串值,也可以创建自己的授权过滤器并设置字段以TempData指明原因.
这是一个简单的自定义过滤器,可以解决这个问题:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
// NOTE: This is not thread safe, it is much better to store this
// value in HttpContext.Items. See Ben Cull's answer below for an example.
private bool _isAuthorized;
protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
{
_isAuthorized = base.AuthorizeCore(httpContext);
return _isAuthorized;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if(!_isAuthorized)
{
filterContext.Controller.TempData.Add("RedirectReason", "Unauthorized");
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的视图中,您可以执行以下操作:
@if(TempData["RedirectReason"] == "Unauthorized")
{
<b>You don't have permission to access that area</b>
}
Run Code Online (Sandbox Code Playgroud)
(虽然我推荐一种比这些神奇琴弦更好的方法,但你明白了这一点)
Ben Cull的方法效果很好,但请记住有两个AuthorizeAttribute类 - 一个在System.Web.HTTP中(由Web API使用),另一个在System.Web.Mvc中.Ben的方法使用System.Web.Mvc类.为清楚起见,我建议使用完全限定的路径.
如果您在MVC旁边使用Web API,则需要实现两个过滤器:
public class AuthorizeRedirectMVCAttribute : System.Web.Mvc.AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult("~/Account/AccessDenied");
}
}
}
public class AuthorizeRedirectAPIAttribute : System.Web.Http.AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
base.HandleUnauthorizedRequest(actionContext);
if (actionContext.RequestContext.Principal.Identity.IsAuthenticated)
{
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Forbidden);
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,asp.net将允许您使用API过滤器装饰您的MVC控制器 - 它不会按您期望的方式工作,因此请保持您的属性名称显式.
| 归档时间: |
|
| 查看次数: |
33883 次 |
| 最近记录: |