使用自定义AuthorizeAttribute

时间:2015-04-22 14:15:01

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

我有自定义授权属性:

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。

3 个答案:

答案 0 :(得分:17)

终于明白了,虽然有人可能会建议一个更好的方法......

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

答案 1 :(得分:0)

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

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

谢谢!

答案 2 :(得分:0)

有很多方法可以实现这一点。 您应该使用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)
         }));

公正,不要忘记设置区域。