Подтвердить что ты не робот

Как перенаправить [Авторизовать] на loginUrl, только если роли не используются?

Я бы хотел, чтобы [Authorize] перенаправлял loginUrl, если я также не использую роль, например [Authorize (Roles="Admin")]. В этом случае я хочу просто показать страницу, в которой пользователь не авторизовался.

Что мне делать?

4b9b3361

Ответ 1

Вот код из моей модифицированной реализации AuthorizeAttribute; Я назвал его SecurityAttribute. Единственное, что я изменил, это метод OnAuthorization, и я добавил дополнительное свойство строки для перенаправления Url на страницу Unauthorized:

// Set default Unauthorized Page Url here
private string _notifyUrl = "/Error/Unauthorized"; 

public string NotifyUrl { 
    get { return _notifyUrl; } set { _notifyUrl = value; } 
}

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

    /// This code added to support custom Unauthorized pages.
    else if (filterContext.HttpContext.User.Identity.IsAuthenticated)
    {
        if (NotifyUrl != null)
            filterContext.Result = new RedirectResult(NotifyUrl);
        else
           // Redirect to Login page.
            HandleUnauthorizedRequest(filterContext);
    }
    /// End of additional code
    else
    {
         // Redirect to Login page.
        HandleUnauthorizedRequest(filterContext);
    }
}

Вы вызываете его так же, как оригинал AuthorizeAttribute, за исключением того, что существует дополнительное свойство для переопределения Unauthorized Page Url:

// Use custom Unauthorized page:
[Security (Roles="Admin, User", NotifyUrl="/UnauthorizedPage")]

// Use default Unauthorized page:
[Security (Roles="Admin, User")]

Ответ 2

Расширьте класс AuthorizeAttribute и переопределите HandleUnauthorizedRequest

public class RoleAuthorizeAttribute : AuthorizeAttribute
{
    private string redirectUrl = "";
    public RoleAuthorizeAttribute() : base()
    {
    }

    public RoleAuthorizeAttribute(string redirectUrl) : base()
    {
        this.redirectUrl = redirectUrl;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            string authUrl = this.redirectUrl; //passed from attribute

            //if null, get it from config
            if (String.IsNullOrEmpty(authUrl))
                authUrl = System.Web.Configuration.WebConfigurationManager.AppSettings["RolesAuthRedirectUrl"];

            if (!String.IsNullOrEmpty(authUrl))
                filterContext.HttpContext.Response.Redirect(authUrl);
        }

        //else do normal process
        base.HandleUnauthorizedRequest(filterContext);
    }
}

Использование

[RoleAuthorize(Roles = "Admin, Editor")]
public class AccountController : Controller
{

}

И убедитесь, что вы добавили запись AppSettings в конфигурацию

<appSettings>
  <add key="RolesAuthRedirectUrl" value="http://mysite/myauthorizedpage" />
</appSettings>

Ответ 3

Самый простой способ, который я нашел, - расширить и настроить атрибут AuthorizeAttribute, чтобы он делал что-то другое (т.е. не задавал HttpUnauthorizedResult), когда проверка роли не удалась. Я написал статью об этом в своем блоге, который может вам пригодиться. В статье описывается то, что вы хотите, хотя оно идет дальше и позволяет пользователю, который "владеет" данными, также иметь доступ к действию. Я думаю, что это довольно легко изменить для ваших целей - вам просто нужно удалить часть "или владельца".