asp.net-mvc 在自定义授权属性中覆盖 AuthorizeCore 会导致“找不到合适的方法来覆盖”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3488348/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Overriding AuthorizeCore in custom Authorize attribute results in "no suitable method found to override" error
提问by JoseMarmolejos
I'm trying to build custom AuthorizeAttribute, so in my Core project (a class library) I have this code:
我正在尝试构建自定义 AuthorizeAttribute,因此在我的核心项目(类库)中,我有以下代码:
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);
}
}
}
When I try to build the thing I get this error: Error 2 'IVC.Core.Attributes.TimeShareAuthorizeAttribute.AuthorizeCore(System.Web.HttpContextBase)': no suitable method found to override...
当我尝试构建东西时,我收到此错误:错误 2 'IVC.Core.Attributes.TimeShareAuthorizeAttribute.AuthorizeCore(System.Web.HttpContextBase)':找不到合适的方法来覆盖...
Am I missing something here? I've searched all over but every site I can find just tells me to do exactly what I did here. I'm using mvc2 btw.
我在这里错过了什么吗?我到处搜索,但我能找到的每个网站都告诉我完全按照我在这里所做的去做。顺便说一句,我正在使用 mvc2。
- Edited to add: if I move the class to the mvc project in the same solution there's no compiler error.
- 编辑添加:如果我将类移动到同一解决方案中的 mvc 项目,则没有编译器错误。
回答by alphadogg
Yeah, I fumbled with that one for a while too and figured it out from the Object browser. It certainly is NOT clear from the MSDN docs unless you scroll all the way down to the user comments on the HttpContextBase class. And, of course, lots of examples on the web, but nobody ever shows the full class file! :)
是的,我也摸索了一段时间,然后从对象浏览器中弄清楚了。除非您一直向下滚动到用户对 HttpContextBase 类的评论,否则从 MSDN 文档中肯定不清楚。而且,当然,网络上有很多示例,但没有人显示完整的类文件!:)
Try adding a reference to System.Web.Abstractions to your project.
尝试将 System.Web.Abstractions 的引用添加到您的项目中。
UPDATE: Just noticed from the MSDN that under v3.5, it is under System.Web.Abstractions, but under v4, it's under System.Web.
更新:刚刚从 MSDN 上注意到,在 v3.5 下,它在 System.Web.Abstractions 下,但在 v4 下,它在 System.Web 下。
回答by mft2010
Here is AuthorizationAttribute.cs
这是 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();
}
}
}
回答by costr
Also, since I've seen this happen before, be careful with letting Visual Studio auto add usings for you. If you're not paying attention you may end up adding System.Web.Http instead of System.Web.Mvc.
另外,因为我以前见过这种情况,所以请小心让 Visual Studio 为您自动添加用途。如果您不注意,您最终可能会添加 System.Web.Http 而不是 System.Web.Mvc。
回答by GrahamJ
I had this error too. It turned out that Visual Studio had added to my ActionFilter by default:
我也有这个错误。事实证明,Visual Studio 默认已添加到我的 ActionFilter 中:
using System.Web.Http;
使用 System.Web.Http;
Even when I added System.Web.Mvc I still got the error. Commenting out System.Web.Http and just using System.Web.Mvc seems to solve the problem for me.
即使当我添加 System.Web.Mvc 时,我仍然遇到错误。注释掉 System.Web.Http 并仅使用 System.Web.Mvc 似乎为我解决了问题。
Hoping this might help someone!
希望这可以帮助某人!
回答by cheny
When I copied my old codes to my new project, the same problem happened.
当我将旧代码复制到新项目时,发生了同样的问题。
It turned out that there are 2 AuthrizeAttributes. One is in System.Web.Mvc, and another in System.Web.Http. The Mvc one has the AuthrizeCore, while the Http one has not.
原来有2个AuthrizeAttributes。一个在 System.Web.Mvc 中,另一个在 System.Web.Http 中。Mvc 有 AuthrizeCore,而 Http 没有。
You might need to add reference to System.Web.Mvc to access the right one.
您可能需要添加对 System.Web.Mvc 的引用以访问正确的引用。
回答by ddagsan
Use System.Web.Mvc
namespace.
使用System.Web.Mvc
命名空间。
Sample code:
示例代码:
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);
}
}
回答by Matthew Moody
Under fw v4.5 it now under System.Web.Mvc apparently.
在 fw v4.5 下,它现在显然在 System.Web.Mvc 下。