我已经编写了一个自定义授权过滤器,用于AngularJS XSRF方法,但是没有调用过滤器。
奇怪的是,我从另一个项目中复制了它,似乎在那里工作正常。
这是attrubute / filter代码。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class ValidateAngularAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
string token = filterContext.RequestContext.HttpContext.Request.Headers["X-XSRF-TOKEN"];
object sessionToken = filterContext.RequestContext.HttpContext.Session["XSRF-TOKEN"];
if (string.IsNullOrEmpty(token) || sessionToken == null || sessionToken.ToString() != token)
{
throw new UnauthorizedAccessException();
}
}
}
在这里它是在WebAPI控制器中装饰一个动作。
[Authorize]
public class WorksOrdersController : ApiController
{
[HttpPost]
[ValidateAngularAntiForgeryToken]
public void EmailJob(int id, EmailModel model)
{
// do something
}
}
我是否必须在Web.config中添加一些内容才能使其正常工作?我无法在实际工作的项目的web.config中看到任何显着不同的东西。
答案 0 :(得分:7)
问题是ASP.NET现在有两个IAuthorizationFilter
接口。
System.Web.Mvc
中的一个用于“普通”视图控制器,另一个用于System.Web.Http.Filters
用于WebAPI。
我在版本中使用了错误的using
语句。
答案 1 :(得分:2)
有两件事可能导致这种行为。
第一次 - 您在控制器中添加了AuthorizeAttribute
。如果在控制器(类)和操作(方法)中有Authorize,则两者都将用于授权。首先,它被称为控制器的授权属性。如果允许访问,则称为操作的授权属性。
默认情况下AuthorizeAttribute
使用Membership
如果您未设置Membership
,则此属性将被拒绝您的访问,并且ValidateAngularAntiForgeryTokenAttribute
将不会被调用。
尝试在控制器之前注释第[Authorize]
行,然后运行测试,看看您的属性是否立即被调用。
第二次 - 尝试将您的属性转换为类似@siva的内容。 k说。像这样:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class ValidateAngularAntiForgeryTokenAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var token = httpContext.Request.RequestContext.HttpContext.Request.Headers["X-XSRF-TOKEN"];
var sessionToken = httpContext.Request.RequestContext.HttpContext.Session["XSRF-TOKEN"];
if (string.IsNullOrEmpty(token) || sessionToken == null || sessionToken.ToString() != token)
{
return false;
}
return true;
}
}
答案 2 :(得分:0)
这个问题是由我造成的,因为我忘记在Application_Start中调用寄存器过滤器方法...这是一个愚蠢的问题,但如果它为某人节省了一天的故障排除,那就值得。
protected void Application_Start(object sender, EventArgs e)
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
}