2010-08-15 12 views
25

Staram się budować niestandardowe AuthorizeAttribute, więc w moim projekcie rdzenia (biblioteka klas) Mam ten kod:Zastępowanie AuthorizeCore w niestandardowym Autoryzacja atrybutów wyniki w „nie nadaje się metoda okaże się zastąpić” Błąd

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

Kiedy próbuję zbudować coś mi ten błąd: Error 2 'IVC.Core.Attributes.TimeShareAuthorizeAttribute.AuthorizeCore (System.Web.HttpContextBase)': nie nadaje się metoda okaże się zastąpić ...

Czy coś mi umyka? Przeszukałem wszystkie strony, ale każda strona, którą mogę znaleźć, po prostu mówi mi, żeby zrobić dokładnie to, co tu zrobiłem. Używam mvc2 btw.

  • Edytowane w celu dodania: jeśli przeniesię klasę do projektu mvc w tym samym rozwiązaniu, nie wystąpi błąd kompilatora.
+0

Sygnatury metod i zastosowania wyglądają niemal identycznie jak coś, co działa dobrze dla mnie ... – Tahbaza

+1

Którą wersję zestawu 'System.Web.Mvc' opisałeś? –

+0

2.0 Myślałem, że to problem, ale sprawdziłem i dwukrotnie sprawdziłem i potrójnie sprawdziłem ... W końcu zostawiłem atrybut w aplikacji internetowej, ale chciałbym wiedzieć, dlaczego powoduje to błąd kompilacji, jeśli go przeniesię do biblioteki klas. – JoseMarmolejos

Odpowiedz

29

Tak, też przez jakiś czas próbowałem go znaleźć i znalazłem go w przeglądarce obiektów. Z pewnością nie jest to jasne z dokumentów MSDN, chyba że przewiniesz całą drogę do komentarzy użytkownika w klasie HttpContextBase. I, oczywiście, wiele przykładów w sieci, ale nikt nigdy nie pokazuje pełnego pliku klasowego! :)

Spróbuj dodać odniesienie do System.Web.Abstractions do swojego projektu.

AKTUALIZACJA: Właśnie zauważyłem z MSDN, że pod wersją 3.5, jest pod System.Web.Abstractions, ale pod v4, jest pod System.Web.

+0

używam mvc 5.2.3. w moim przypadku nawet odwołuję się do 'System.Web.Abstractions' w moim projekcie, nie mogę zaimportować przestrzeni nazw za pomocą' używając' słowa kluczowego –

23

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

    } 
} 
6

Ponadto, ponieważ widziałem to się stało wcześniej, należy być ostrożnym z najmu Visual Studio automatycznie dodać usings dla Ciebie. Jeśli nie zwracasz uwagi, możesz dodać System.Web.Http zamiast System.Web.Mvc.

0

Pod FW v4.5 to widocznie pod System.Web.Mvc.

2

Kiedy skopiowałem stare kody do mojego nowego projektu, wystąpił ten sam problem.

Okazało się, że istnieją 2 AuthrizeAttributes. Jedna jest w System.Web.Mvc, a druga w System.Web.Http. MVc ma AuthrizeCore, a Http nie.

Może być konieczne dodanie odniesienia do System.Web.Mvc, aby uzyskać dostęp do właściwego.

0

Użyj przestrzeni nazw .

Przykładowy kod:

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

miałem ten błąd też. Okazało się, że Visual Studio dodało domyślnie mój ActionFilter:

przy użyciu System.Web.Http;

Nawet gdy dodałem System.Web.Mvc nadal mam błąd. Komentowanie Out.Web.Http i po prostu przy użyciu System.Web.Mvc wydaje się rozwiązać problem dla mnie.

Mam nadzieję, że to może komuś pomóc!

Powiązane problemy