【问题标题】:Custom Authorize attribute with redirect to original URL具有重定向到原始 URL 的自定义授权属性
【发布时间】:2017-06-19 15:35:26
【问题描述】:

我以前一直在用我自己的类和 if 语句处理角色/访问权限,其中保存了用户的原始 URL,以防他甚至没有登录,一旦用户登录,他就会被重定向到他的原始页面。现在下面是我的旧代码。我很难在我的自定义授权属性中使用相同的逻辑。请指导。谢谢

(旧方法)每个动作方法中的包装器

[HttpGet]
        public ActionResult Index(string DealType)
        {
            User user = Session["CurrentUser"] as User;
            if (user != null)
            {
                if (user.IsInRole(RoleType.MASTER) || user.IsInRole(RoleType.VIEW))
                {
                    // Money Shot
                    List<Deal> deals = dataBase.Deals.Where(d => d.DealType.Equals(DealType)).ToList();

                    return View(deals);
                }
                else
                {
                    return PartialView("_unauthorize");
                }
            }
            else
            {
// I need to handle this part in custom attribute
                return RedirectToAction("Login", "User", new { RedirectURL= string.Format("/{0}/{1}", "Deal", "Index") });
            }
        } 

在我的登录操作方法中我使用了这个

public ActionResult Login(User model){
//Code of matching username and password...
//Validations/ exceptions handling of incorrect passwords

 if (!string.IsNullOrEmpty(RedirectURL))
                            {
                                return Redirect(RedirectURL);
                            }
                            else
                            {
                                return RedirectToAction("Index", "Home");
                            }
}

现在因为我了解了自定义属性,所以我像下面这样应用它们

public class AuthorizeUserAttribute : AuthorizeAttribute
{
    public AuthorizeUserAttribute(params RoleType[] roleTypes)
    {
        AccessLevels = roleTypes;
    }

    // Custom property
    public RoleType[] AccessLevels { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        User user = HttpContext.Current.Session["CurrentUser"] as User;

        if (user != null)
        {
            if (user.IsInRole(AccessLevels))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
//redirect URL should be save here but this is boolean method!
                return false;
            }
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary(
                        new
                        {
                            controller = "User",
                            action = "Unauthorised"
                        })
                    );
    }
}

我是这样用的

[AuthorizeUser(RoleType.DELETE, RoleType.ADMIN)]

现在的问题是,如果用户完全没有登录,他正在访问的 URL 应该被保存,一旦他登录,他应该被重定向到他来自的地方。希望我解释清楚。

【问题讨论】:

  • 您似乎在这里重新发明轮子。默认情况下,当重定向到登录页面时,ASP.NET 已经跟踪 URL。尝试创建一个新的 MVC 4/5 项目,您可以看到它是如何完成的。
  • 是的,我知道,但我没有使用身份框架,这个 URL 重定向变量在授权属性中可用吗?

标签: asp.net-mvc redirect attributes authorization


【解决方案1】:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            RedirectToRouteResult routeData = null;
            var returnUrl = string.Empty;

            if(filterContext.HttpContext.Request.Url != null)
                 returnUrl = filterContext.HttpContext.Request.Url.LocalPath;

            if (CurrentUser == null)
                routeData = new RedirectToRouteResult(
                    new RouteValueDictionary(new {controller = "Account", action = "Login", returnUrl = returnUrl}));
            else
                routeData = new RedirectToRouteResult(
                    new RouteValueDictionary(new {controller = "Error", action = "AccessDenied"}));

            filterContext.Result = routeData;
        }

在上面的代码中(在您的自定义 AuthorizeAttribute 中),您可以使用可用的请求信息捕获返回 URL。

这将使您的 returnUrl 在 Request.QueryString[] 字典中可用。

在您的登录视图中,您需要放置类似这样的内容以使其可操作。

@{
    ViewBag.ReturnUrl = Request.QueryString["returnUrl"];
}

然后在您的登录表单中:

@using (Html.BeginForm("Login", "Account", new {returnUrl = ViewBag.ReturnUrl}, FormMethod.Post, new{@class="form-horizontal form-material", @onsubmit="return loading_event();", @id="loginForm"}))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多