基本上我想在某人不属于我的属性中列出的角色时显示友情消息。目前我的应用程序只是将用户吐回到登录屏幕。我已经阅读了一些关于创建一个仅扩展[AuthorizeAttribute]的自定义属性的帖子,但我认为必须有一些开箱即用的东西才能做到这一点?
有人可以指出我正确的方向,我需要看到没有它将用户发送到登录表单,而只是向他们拍摄“未授权”的消息?
答案 0 :(得分:6)
我可能会稍微添加我的$ 0.02,但是当您创建CustomAuthorizationAttribue时,可以使用AuthorizationContext.Result property来指示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: ...
}
答案 1 :(得分:3)
几天前我遇到了这个问题,解决方案有点详细,但这里有重要的内容。在AuthorizeAttribute
中,OnAuthorization
方法在授权失败时返回HttpUnauthorizedResult
,这使得返回自定义结果有点困难。
我最终做的是创建一个CustomAuthorizeAttribute类并重写OnAuthorization方法来引发异常。然后,我可以使用自定义错误处理程序捕获该异常并显示自定义错误页面,而不是返回401(未授权)。
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;
以启用自定义错误。
答案 2 :(得分:2)
如果你想要简单或完全控制逻辑,你可以在你的动作方法中调用它:
User.IsInRole("NameOfRole");
它返回一个bool,你可以根据结果完成其余的逻辑。
我在某些情况下使用的另一个是:
System.Web.Security.Roles.GetRolesForUser();
我认为这会返回一个字符串[],但不要引用我。
修改强> 一个例子总是有帮助...
public ActionResult AddUser()
{
if(User.IsInRoles("SuperUser")
{
return View("AddUser");
}
else
{
return View("SorryWrongRole");
}
}
只要您的返回类型为“ActionResult”,您就可以返回任何接受的返回类型(ViewResult,PartialViewResult,RedirectResult,JsonResult ......)
答案 3 :(得分:2)
非常类似于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);
}
}
}
答案 4 :(得分:0)
开箱即用的行为是[Authorize]属性返回HTTP 401.FormsAuthenticationModule(默认加载)拦截此401并将用户重定向到登录页面。看一下Reflector中的System.Web.Security.FormsAuthenticationModule :: OnLeave来看看我的意思。
如果您希望AuthorizeAttribute执行 other 而不是返回HTTP 401,则必须覆盖AuthorizeAttribute :: HandleUnauthorizedRequest方法并在其中执行自定义逻辑。或者,只需更改〜\ Web.config的这一部分:
<forms loginUrl="~/Account/LogOn" timeout="2880" />
并指向其他网址,例如〜/ AccessDenied。