【发布时间】:2014-02-21 03:22:04
【问题描述】:
我想重写 API 控制器以检查所有 HttpGet 和 HttpPost 调用的标头中的某些值,因为它们是在不包括用于检查每个调用的代码的情况下进行的。目前我的方法如下:
public class MyApiController : ApiController
{
[HttpGet]
public HttpResponseMessage GetAccountById()
{
var accountId = (Request.Headers.Where(t => t.Key == "accountid").Count() == 0) ? null : Request.Headers.GetValues("accountid").First();
var apiKey = (Request.Headers.Where(t => t.Key == "apikey").Count() == 0) ? null : Request.Headers.GetValues("apikey").First();
if (String.IsNullOrEmpty(accountId)) {
return Request.CreateResponse(HttpStatusCode.Forbidden, "Please provide an Account Id.");
}
if (String.IsNullOrEmpty(apiKey)) {
return Request.CreateResponse(HttpStatusCode.Forbidden, "Please provide an Account Api Key.");
}
// Get Account
// return Account;
}
}
我怎样才能在每次通话中进行 apikey/accountid 检查,而不必将检查写入每个通话中?
解决方案:覆盖 DelegatingHandler 效果很好。
ApiSecurityHandler.cs
public class ApiSecurityHandler : DelegatingHandler
{
public ApiSecurityHandler(HttpConfiguration httpConfiguration)
{
InnerHandler = new HttpControllerDispatcher(httpConfiguration);
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var accountId = (request.Headers.Where(t => t.Key == "accountid").Count() == 0) ? null : request.Headers.GetValues("accountid").First();
var apiKey = (request.Headers.Where(t => t.Key == "apikey").Count() == 0) ? null : request.Headers.GetValues("apikey").First();
if (String.IsNullOrEmpty(accountId)) {
var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
response.Content = new StringContent("Please provide an Account Id.");
var tsc = new TaskCompletionSource<HttpResponseMessage>();
tsc.SetResult(response);
return tsc.Task;
}
if (String.IsNullOrEmpty(apiKey)) {
var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
response.Content = new StringContent("Please provide an Account Api Key.");
var tsc = new TaskCompletionSource<HttpResponseMessage>();
tsc.SetResult(response);
return tsc.Task;
}
// Authorize the Account Id and Api Key here
using (var accountManager = new AccountManager()) {
if (!accountManager.AuthorizeAccountApiKey(accountId, apiKey)) {
var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
response.Content = new StringContent("Api authorization denied.");
var tsc = new TaskCompletionSource<HttpResponseMessage>();
tsc.SetResult(response);
return tsc.Task;
}
}
return base.SendAsync(request, cancellationToken);
}
}
在您的路由配置中,只需将此参数添加到地图路由:
handler: new ApiSecurityHandler(GlobalConfiguration.Configuration)
【问题讨论】:
标签: c# asp.net asp.net-mvc api