Переопределение AuthorizeCore в настраиваемом атрибуте Authorize приводит к тому, что не найдено подходящего метода для переопределения ошибки

Я пытаюсь создать собственный атрибут AuthorizeAttribute, поэтому в моем проекте Core (библиотека классов) у меня есть этот код:

using System;
using System.Web;
using System.Web.Mvc;
using IVC.Core.Web;
using System.Linq;

namespace IVC.Core.Attributes
{
    public class TimeShareAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if(!httpContext.Request.IsAuthenticated)
                return false;

            var rolesProvider = System.Web.Security.Roles.Providers["TimeShareRoleProvider"];

            string[] roles = rolesProvider.GetRolesForUser(httpContext.User.Identity.Name);

            if(roles.Contains(Website.Roles.RegisteredClient, StringComparer.OrdinalIgnoreCase))
            {
                return true;
            }

            return false;
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.Result = new RedirectResult("/TimeShare/Account/LogOn");

            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

Когда я пытаюсь построить эту штуку, я получаю эту ошибку: Ошибка 2 «IVC.Core.Attributes.TimeShareAuthorizeAttribute.AuthorizeCore (System.Web.HttpContextBase)»: не найдено подходящего метода для переопределения ...

Я что-то упустил? Я искал повсюду, но каждый сайт, который я могу найти, просто говорит мне делать именно то, что я делал здесь. Кстати, я использую mvc2.

  • Отредактировано для добавления: если я перемещу класс в проект mvc в том же решении, ошибки компилятора не будет.

person JoseMarmolejos    schedule 15.08.2010    source источник
comment
Сигнатуры методов и их использование выглядят почти идентичными тому, что мне хорошо подходит ...   -  person Tahbaza    schedule 15.08.2010
comment
На какую версию сборки System.Web.Mvc вы ссылались?   -  person Darin Dimitrov    schedule 16.08.2010
comment
2.0 Я думал, что это проблема, но я проверил, дважды проверил и трижды проверил ... В итоге я оставил атрибут в веб-приложении, чтобы двигаться дальше, но мне бы хотелось знать, почему он выдает эту ошибку компилятора, если я перемещаю его в библиотека классов.   -  person JoseMarmolejos    schedule 16.08.2010
comment
Может быть, в библиотеке классов есть неправильная ссылка на mvc 1.0 ?!   -  person Christian13467    schedule 16.08.2010
comment
Я удалил ссылку и добавил ее снова, но все равно получаю ту же ошибку. Думаю, это морщина, которая будет жить с проектом ...   -  person JoseMarmolejos    schedule 17.08.2010
comment
Что-то, что я узнал (из этого сообщения): Если вы хотите, чтобы вызов HandleUnauthorizedRequest возвращался к другому действию, вы не можете вызвать base.HandleUnauthorizedRequest(filterContext)   -  person mateuscb    schedule 07.10.2011
comment
использовать пространство имен System.Web.Mvc, а не System.Web.Http   -  person Timeless    schedule 18.07.2014


Ответы (7)


Да, я тоже некоторое время возился с этим и выяснил это из браузера объектов. Это, конечно, НЕ ясно из документов MSDN, если вы не прокрутите полностью до комментариев пользователя в классе HttpContextBase. И, конечно же, множество примеров в сети, но никто никогда не показывает полный файл класса! :)

Попробуйте добавить ссылку на System.Web.Abstractions в свой проект.

ОБНОВЛЕНИЕ: только что заметил из MSDN, что в версии 3.5 он находится в разделе System.Web.Abstractions, а в версии 4 - в разделе System.Web.

person alphadogg    schedule 22.08.2010
comment
Я использую mvc 5.2.3. в моем случае, даже если я ссылался на System.Web.Abstractions в своем проекте, я не мог импортировать пространство имен с помощью ключевого слова using - person Beingnin; 18.01.2018

Вот AuthorizationAttribute.cs

/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This software is subject to the Microsoft Public License (Ms-PL).
* A copy of the license can be found in the license.htm file included
* in this distribution.
*
* You must not remove this notice, or any other, from this software.
*
* ***************************************************************************/

namespace System.Web.Mvc {
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;
    using System.Security.Principal;
    using System.Web;

[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
Justification = "Unsealed so that subclassed types can set properties in the default constructor or override our behavior.")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter {

        private string _roles;
        private string[] _rolesSplit = new string[0];
        private string _users;
        private string[] _usersSplit = new string[0];

        public string Roles {
            get {
                return _roles ?? String.Empty;
            }
            set {
                _roles = value;
                _rolesSplit = SplitString(value);
            }
        }

        public string Users {
            get {
                return _users ?? String.Empty;
            }
            set {
                _users = value;
                _usersSplit = SplitString(value);
            }
        }

        // This method must be thread-safe since it is called by the thread-safe OnCacheAuthorization() method.
        protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
            if (httpContext == null) {
                throw new ArgumentNullException("httpContext");
            }

            IPrincipal user = httpContext.User;
            if (!user.Identity.IsAuthenticated) {
                return false;
            }

            if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) {
                return false;
            }

            if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)) {
                return false;
            }

            return true;
        }

        private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus) {
            validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
        }

        public virtual void OnAuthorization(AuthorizationContext filterContext) {
            if (filterContext == null) {
                throw new ArgumentNullException("filterContext");
            }

            if (AuthorizeCore(filterContext.HttpContext)) {
                // ** IMPORTANT **
                // Since we're performing authorization at the action level, the authorization code runs
                // after the output caching module. In the worst case this could allow an authorized user
                // to cause the page to be cached, then an unauthorized user would later be served the
                // cached page. We work around this by telling proxies not to cache the sensitive page,
                // then we hook our custom authorization code into the caching mechanism so that we have
                // the final say on whether a page should be served from the cache.

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

        // This method must be thread-safe since it is called by the caching module.
        protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext) {
            if (httpContext == null) {
                throw new ArgumentNullException("httpContext");
            }

            bool isAuthorized = AuthorizeCore(httpContext);
            return (isAuthorized) ? HttpValidationStatus.Valid : HttpValidationStatus.IgnoreThisRequest;
        }

        internal static string[] SplitString(string original) {
            if (String.IsNullOrEmpty(original)) {
                return new string[0];
            }

            var split = from piece in original.Split(',')
                        let trimmed = piece.Trim()
                        where !String.IsNullOrEmpty(trimmed)
                        select trimmed;
            return split.ToArray();
        }

    }
}
person mft2010    schedule 28.01.2011

Кроме того, поскольку я видел это раньше, будьте осторожны, позволяя Visual Studio автоматически добавлять использование. Если вы не обращаете внимания, вы можете добавить System.Web.Http вместо System.Web.Mvc.

person costr    schedule 18.06.2013

Когда я скопировал свои старые коды в новый проект, возникла та же проблема.

Оказалось, что есть 2 AuthrizeAttributes. Один находится в System.Web.Mvc, а другой в System.Web.Http. У Mvc есть AuthrizeCore, а у Http - нет.

Возможно, вам потребуется добавить ссылку на System.Web.Mvc, чтобы получить доступ к нужному.

person cheny    schedule 12.04.2015

У меня тоже была эта ошибка. Оказалось, что Visual Studio по умолчанию добавила в мой ActionFilter:

using System.Web.Http;

Даже когда я добавил System.Web.Mvc, я все равно получал ошибку. Комментируя System.Web.Http и просто используя System.Web.Mvc, похоже, решает проблему для меня.

Надеюсь, это может кому-то помочь!

person GrahamJ    schedule 05.12.2016

Используйте пространство имен System.Web.Mvc.

Образец кода:

using System.Web.Mvc;

public class CustomAuthorize : AuthorizeAttribute
{
    protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
    {
        var service = new AuthService();
        return service.GetCurrentUser() != null;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);
    }
}
person ddagsan    schedule 06.11.2015

Под fw v4.5 он, по-видимому, теперь находится в System.Web.Mvc.

person Matthew Moody    schedule 14.01.2015