【问题标题】:Generate a return Url with a custom AuthorizeAttribute使用自定义 AuthorizeAttribute 生成返回 URL
【发布时间】:2018-12-02 07:47:52
【问题描述】:

我有一个自定义的授权属性:

using System;
using System.Web.Mvc;
using System.Web.Routing;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAuthenticated)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Login", action = "Login" }));
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

...我用来装饰某些控制器的:

[MyAuthorizeAttribute(Roles = "Superman, Batman, Spiderman")]
public class SuperHeroController : Controller
{
    // ....
}

谁能解释一下如何修改授权代码,以便如果授权失败,登录 URL 包含ReturnUrl(当前控制器/方法的 URL)?

这基本上是在尝试模仿 Web 表单 ReturnUrl 逻辑,但采用一种智能方式,因此我不必手动为 URL 使用字符串。

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-5.2


    【解决方案1】:

    终于想通了,虽然有人可能会提出更好的方法......

    filterContext.Result = new RedirectToRouteResult(
                            new RouteValueDictionary(
                                new
                                {
                                    controller = "Login",
                                    action = "Login",
                                    returnUrl = filterContext.HttpContext.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.SafeUnescaped)
                                }));
    

    【讨论】:

    • 我遇到了同样的问题。这个帮助!
    • 如上。谢谢你,正是我需要的:)
    • 如果您使用的是 .NET 3 或更高版本,那么 request.URL 将不起作用。查看答案:stackoverflow.com/a/69765256/8750262
    【解决方案2】:

    有很多方法可以实现这一点。 你应该使用filterContext.HttpContext.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.SafeUnescaped) 来获取returnUrl。

    第一种方式:

     var returnUrl = filterContext.HttpContext.Request.Url?.GetComponents(UriComponents.PathAndQuery, UriFormat.SafeUnescaped) ?? "";
     if (!string.IsNullOrWhiteSpace(returnUrl))
     {
           returnUrl = "/" + returnUrl;
     }
    
     filterContext.Result = new RedirectResult($"~/Login/Login{returnUrl}");
    

    第二种方式:

    filterContext.Result = new RedirectToRouteResult(
        new RouteValueDictionary(
            new
            {
                  controller = "Login",
                  action = "Login",
                  area = "",
                  returnUrl = filterContext.HttpContext.Request.Url?.GetComponents(UriComponents.PathAndQuery,
                                UriFormat.SafeUnescaped)
             }));
    

    只是,不要忘记设置区域。

    【讨论】:

      【解决方案3】:

      这正是我解决相同问题所需要的,虽然看起来略有不同:

      filterContext.Result = new RedirectToRouteResult(
                      new RouteValueDictionary
                      {
                          { "controller", "Account" },
                          { "action", "Login" },
                          { "returnUrl", filterContext.HttpContext.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.SafeUnescaped) }
                      });
      

      谢谢!

      【讨论】:

        猜你喜欢
        • 2020-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-27
        • 1970-01-01
        • 2016-01-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多