.net MVC 控制器操作方法的属性

发布于 2024-08-17 06:42:29 字数 190 浏览 7 评论 0原文

本质上,当某人不属于我的属性中列出的角色时,我想显示一条友好的消息。目前,我的应用程序只是将用户返回到登录屏幕。我读过一些关于创建仅扩展 [AuthorizeAttribute] 的自定义属性的文章,但我认为必须有一些开箱即用的东西来做到这一点?

有人可以指出我需要查看的正确方向,不要让它将用户发送到登录表单,而只是向他们发送“未经授权”的消息吗?

Essentially I want to show a friendly message when someone is not part of a role listed in my attribute. Currently my application just spits the user back to the log in screen. I've read a few posts that talk about creating a custom attribute that just extends [AuthorizeAttribute], but I'm thinking there's got to be something out of the box to do this?

can someone please point me in the right direction of where I need to look to not have it send the user to the log in form, but rather just shoot them a "not authorized" message?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

卖梦商人 2024-08-24 06:42:29

我添加 0.02 美元可能有点晚了,但是当您创建 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: ...
}

I might be a little late in adding my $0.02, but when you create your CustomAuthorizationAttribue, you can use the AuthorizationContext.Result property to dictate where the AuthorizeAttribute.HandleUnauthorizedRequest method directs the user.

Here is a very simple example that allows you to specify the URL where a user should be sent after a failed authorization:

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);
    }
}

And if I wanted to redirect the user to /Error/Unauthorized as suggested in a previous post:

[Authorize2(Roles = "AuthorizedUsers", RedirectResultUrl = "/Error/Unauthorized")]
public ActionResult RestrictedAction()
{
    // TODO: ...
}
月光色 2024-08-24 06:42:29

几天前我遇到了这个问题,解决方案有点详细,但这里是重要的部分。在 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; 以启用自定义错误。

I ran into this issue a few days ago and the solution is a bit detailed but here are the important bits. In AuthorizeAttribute the OnAuthorization method returns a HttpUnauthorizedResult when authorization fails which makes returning a custom result a bit difficult.

What I ended up doing was to create a CustomAuthorizeAttribute class and override the OnAuthorization method to throw an exception instead. I can then catch that exception with a custom error handler and display a customized error page instead of returning a 401 (Unauthorized).

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");                
        }
    }
}

then in your web.config you can set custom handlers for specific errors:

    <customErrors mode="On" defaultRedirect="~/Error">
        <error statusCode="401" redirect="~/Error/Unauthorized" />
        <error statusCode="404" redirect="~/Error/NotFound" />
    </customErrors>

and then implement your own ErrorController to serve up custom pages.

On IIS7 you need to look into setting Response.TrySkipIisCustomErrors = true; to enable your custom errors.

吻风 2024-08-24 06:42:29

如果您想要逻辑的简单性或完全控制,您可以在操作方法中调用它:

User.IsInRole("NameOfRole");

它返回一个布尔值,您可以根据该结果执行其余的逻辑。

我在某些情况下使用的另一种方法是:

System.Web.Security.Roles.GetRolesForUser();

我认为返回一个 string[] 但不要引用我的观点。

编辑:
一个示例总是有帮助的...

public ActionResult AddUser()
{
    if(User.IsInRoles("SuperUser")
    {
        return View("AddUser");
    }
    else
    {
        return View("SorryWrongRole");
    }
}

只要您的返回类型是“ActionResult”,您就可以返回任何接受的返回类型(ViewResult、PartialViewResult、RedirectResult、JsonResult...)

If simplicity or total control of the logic is what you want you can call this in your action method:

User.IsInRole("NameOfRole");

It returns a bool and you can do the rest of your logic depending on that result.

Another one that I've used in some cases is:

System.Web.Security.Roles.GetRolesForUser();

I think that returns a string[] but don't quote me on that.

EDIT:
An example always helps...

public ActionResult AddUser()
{
    if(User.IsInRoles("SuperUser")
    {
        return View("AddUser");
    }
    else
    {
        return View("SorryWrongRole");
    }
}

As long as your return type is "ActionResult" you could return any of the accepted return types (ViewResult, PartialViewResult, RedirectResult, JsonResult...)

酒儿 2024-08-24 06:42:29

与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);
        }
    }
}

Very similar to crazyarabian, but I only redirect to my string if the user is actually authenticated. This allows the attribute to redirect to the standard logon page if they are not currently logged in, but to another page if they don't have permissions to access the 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);
        }
    }
}
归属感 2024-08-24 06:42:29

开箱即用的行为是 [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。

The out-of-the-box behavior is that the [Authorize] attribute returns an HTTP 401. The FormsAuthenticationModule (which is loaded by default) intercepts this 401 and redirects the user to the login page. Take a look at System.Web.Security.FormsAuthenticationModule::OnLeave in Reflector to see what I mean.

If you want the AuthorizeAttribute to do something other than return HTTP 401, you'll have to override the AuthorizeAttribute::HandleUnauthorizedRequest method and perform your custom logic in there. Alternatively, just change this part of ~\Web.config:

<forms loginUrl="~/Account/LogOn" timeout="2880" />

And make it point to a different URL, like ~/AccessDenied.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文