我希望当某人不属于我的属性列表中的角色时,能够显示友好的消息。目前,我的应用程序只会将用户弹回登录界面。我读了一些帖子,讨论了创建一个自定义属性,仅扩展[AuthorizeAttribute],但我认为肯定有一些开箱即用的东西可以做到这一点吧?
请问有人可以指导我应该去哪里查找,以便不要将用户发送到登录表单,而是直接向他们发送“未经授权”的消息?
我希望当某人不属于我的属性列表中的角色时,能够显示友好的消息。目前,我的应用程序只会将用户弹回登录界面。我读了一些帖子,讨论了创建一个自定义属性,仅扩展[AuthorizeAttribute],但我认为肯定有一些开箱即用的东西可以做到这一点吧?
请问有人可以指导我应该去哪里查找,以便不要将用户发送到登录表单,而是直接向他们发送“未经授权”的消息?
可能有点晚了,但是当你创建自定义的CustomAuthorizationAttribue时,可以使用AuthorizationContext.Result属性来指定AuthorizeAttribute.HandleUnauthorizedRequest方法将用户重定向到何处。
这里有一个非常简单的示例,允许您指定在授权失败后应将用户发送到的URL:
public class Authorize2Attribute : AuthorizeAttribute
{
// Properties
public String RedirectResultUrl { get; set; }
// Constructors
public Authorize2Attribute()
: base()
{
}
// Overrides
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (String.IsNullOrEmpty(RedirectResultUrl))
base.HandleUnauthorizedRequest(filterContext);
else
filterContext.Result = new RedirectResult(RedirectResultUrl);
}
}
如果我想像之前的帖子所建议的那样将用户重定向到 /Error/Unauthorized,应该怎么做:
[Authorize2(Roles = "AuthorizedUsers", RedirectResultUrl = "/Error/Unauthorized")]
public ActionResult RestrictedAction()
{
// TODO: ...
}
AuthorizeAttribute
中,当授权失败时,OnAuthorization
方法会返回HttpUnauthorizedResult
,这使得返回自定义结果变得有些困难。public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public virtual void OnAuthorization(AuthorizationContext filterContext) {
if (filterContext == null) {
throw new ArgumentNullException("filterContext");
}
if (AuthorizeCore(filterContext.HttpContext)) {
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan(0));
cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
}
else {
// auth failed, redirect to login page
// filterContext.Result = new HttpUnauthorizedResult();
throw new HttpException ((int)HttpStatusCode.Unauthorized, "Unauthorized");
}
}
}
然后,在您的web.config文件中,您可以为特定错误设置自定义处理程序:
<customErrors mode="On" defaultRedirect="~/Error">
<error statusCode="401" redirect="~/Error/Unauthorized" />
<error statusCode="404" redirect="~/Error/NotFound" />
</customErrors>
然后实现自己的ErrorController来提供自定义页面。
在IIS7上,您需要设置Response.TrySkipIisCustomErrors = true;
来启用自定义错误。
User.IsInRole("NameOfRole");
它返回一个布尔值,您可以根据该结果执行其他逻辑。
另一个我在某些情况下使用的是:
System.Web.Security.Roles.GetRolesForUser();
public ActionResult AddUser()
{
if(User.IsInRoles("SuperUser")
{
return View("AddUser");
}
else
{
return View("SorryWrongRole");
}
}
与crazyarabian非常相似,但我只在用户已经通过身份验证时才将其重定向到我的字符串。这允许属性在用户未登录时重定向到标准登录页面,但如果他们没有权限访问url,则重定向到另一个页面。
public class EnhancedAuthorizeAttribute : AuthorizeAttribute
{
public string UnauthorizedUrl { get; set; }
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
var redirectUrl = UnauthorizedUrl;
if (filterContext.HttpContext.User.Identity.IsAuthenticated && !string.IsNullOrWhiteSpace(redirectUrl))
{
filterContext.Result = new RedirectResult(redirectUrl);
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
默认情况下,[Authorize] 属性的行为是返回 HTTP 401。FormsAuthenticationModule(默认加载)拦截此 401 并将用户重定向到登录页面。请查看 Reflector 中的 System.Web.Security.FormsAuthenticationModule::OnLeave。
如果您希望 AuthorizeAttribute 做一些其他事情而不是返回 HTTP 401,则必须覆盖 AuthorizeAttribute::HandleUnauthorizedRequest 方法,并在其中执行自定义逻辑。或者,只需更改 ~\Web.config 的此部分:
<forms loginUrl="~/Account/LogOn" timeout="2880" />
并将其指向不同的URL,例如~/AccessDenied。