C# 如何在控制器上添加Web API身份验证过滤器?
我基于这个链接实现了WebAPI2,身份验证过滤器 过滤器工作,但我无法在控制器上应用?我只能像这样在全球范围内应用它C# 如何在控制器上添加Web API身份验证过滤器?,c#,authentication,filter,asp.net-web-api2,C#,Authentication,Filter,Asp.net Web Api2,我基于这个链接实现了WebAPI2,身份验证过滤器 过滤器工作,但我无法在控制器上应用?我只能像这样在全球范围内应用它 public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Filters.Add(new MyAuthenticationFilter()); // Global level MyAuthentication
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new MyAuthenticationFilter()); // Global level
MyAuthenticationFilter实现
using Test1.Web.Areas.Api.Models;
using Test1.Web.Areas.Api.Provisioning;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Filters;
public class MyAuthenticationFilter : IAuthenticationFilter
{
private static CustomerService = new CustomerService();
public bool AllowMultiple => true;
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
// 1. Look for credentials in the request.
HttpRequestMessage request = context.Request;
AuthenticationHeaderValue authorization = request.Headers.Authorization;
// 2. If there are no credentials, do nothing.
if (authorization == null)
{
this.SetContextErrorResult(context);
return;
}
string apiKey = authorization.Scheme;
// 3. If there are credentials, check Schema exists. Schema has tapiKey value.
// Authorization: apiKey
if (string.IsNullOrWhiteSpace(apiKey))
{
this.SetContextErrorResult(context);
return;
}
// 4. Validate tenant. Here we could use caching
CustomerModel customer = CustomerService.Find(apiKey);
if (customer == null)
{
this.SetContextErrorResult(context);
return;
}
// 5. Credentials ok, set principal
IPrincipal principal = new GenericPrincipal(new GenericIdentity(apiKey), new string[] { });
context.Principal = principal;
return;
}
public async Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
// currently we don't need authentication challenge
return;
}
private void SetContextErrorResult(HttpAuthenticationContext context)
{
context.ErrorResult = new AuthenticationFailedResponse();
}
}
public class AuthenticationFailedResponse : IHttpActionResult
{
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Execute());
}
private HttpResponseMessage Execute()
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent(JsonConvert.SerializeObject(new ApiErrorModel()
{
Message = "Authentication failed",
Description = "Missing or incorrect credentials"
}), Encoding.UTF8, "application/json")
};
return response;
}
}
使用Test1.Web.Areas.Api.Models;
使用Test1.Web.Areas.Api.Provisioning;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Net.Http;
使用System.Net.Http.Header;
使用System.Security.Principal;
使用系统线程;
使用System.Threading.Tasks;
使用System.Web.Http.Filters;
公共类MyAuthenticationFilter:IAAuthenticationFilter
{
私有静态CustomerService=新CustomerService();
public bool AllowMultiple=>true;
公共异步任务AuthenticateAsync(HttpAuthenticationContext上下文,CancellationToken CancellationToken)
{
//1.在请求中查找凭据。
HttpRequestMessage请求=context.request;
AuthenticationHeaderValue authorization=request.Headers.authorization;
//2.如果没有凭据,请不要执行任何操作。
if(授权==null)
{
this.SetContextErrorResult(上下文);
返回;
}
字符串apiKey=authorization.Scheme;
//3.如果有凭据,请检查架构是否存在。架构具有tapiKey值。
//授权:apiKey
if(string.IsNullOrWhiteSpace(apiKey))
{
this.SetContextErrorResult(上下文);
返回;
}
//4.验证租户。在这里我们可以使用缓存
CustomerModel customer=CustomerService.Find(apiKey);
如果(客户==null)
{
this.SetContextErrorResult(上下文);
返回;
}
//5.凭证确定,设置主体
IPrincipal principal=new GenericPrincipal(new genericientity(apiKey),new string[]{});
context.Principal=Principal;
返回;
}
公共异步任务ChallengeAsync(HttpAuthenticationChallengeContext,CancellationToken CancellationToken)
{
//目前我们不需要验证挑战
返回;
}
私有void SetContextErrorResult(HttpAuthenticationContext上下文)
{
context.ErrorResult=新身份验证失败响应();
}
}
公共类身份验证失败响应:IHttpActionResult
{
公共任务执行同步(CancellationToken CancellationToken)
{
返回Task.FromResult(Execute());
}
私有HttpResponseMessageExecute()
{
HttpResponseMessage response=新的HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content=new-StringContent(JsonConvert.SerializeObject(new-apErrorModel())
{
Message=“身份验证失败”,
Description=“凭据缺失或不正确”
}),Encoding.UTF8,“应用程序/json”)
};
返回响应;
}
}
我的一位同事找到了解决方案:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyAuthenticationFilter : FilterAttribute, IAuthenticationFilter
上层代码必须添加到MyAuthentication中。现在我们可以在控制器上使用它:
[ApiExceptionFilter]
[RoutePrefix("api/provisioning/v0")]
[MyAuthenticationFilter]
public class ProvisioningController : ApiController
首先从webconfig中删除以下代码
config.Filters.Add(new MyAuthenticationFilter()); // Global level
然后在控制器上添加属性。首先确保您已经添加了该auhthenticationfilter的名称空间。并使用ActionFilterAttribute和override方法OnActionExecution扩展您的类。您如何尝试将其应用于控制器类?您正在使用[Authorize]属性吗?是的,但我认为
[MyAuthentication]
会起作用。我尝试了[Authorize]
,但它确实应用了其他一些内置的身份验证。请参阅: