我目前正在使用在 OWIN/Katana 上运行的 WebAPI。我定义了两个消息处理程序:
CorsHandler
:允许 CORS(跨域资源共享),将应用于所有 HTTP 消息HmacAuthenticationHandler
:检查用户是否通过身份验证,仅应用于需要身份验证的路由。
我HttpConfiguration
将这样配置:
var config = new HttpConfiguration();
/* configure routes for the web API */
// ### public routes ###
config.Routes.MapHttpRoute("IndexRoute", "", new {controller = "Main", action = "get"});
config.Routes.MapHttpRoute("LoginRoute", "login", new {controller = "Account", action = "Login"});
config.Routes.MapHttpRoute("RegisterRoute", "register", new {controller = "Account", action = "Register"});
// ### routes that need authentication ###
// according to http://www.asp.net/web-api/overview/working-with-http/http-message-handlers (last example)
// List of delegating handlers.
var handlers = new DelegatingHandler[] {
new HmacAuthenticationHandler(controllerConfig.StorageHelper.UserLoginInfo)
};
// Create a message handler chain with an end-point.
var routeHandlers = HttpClientFactory.CreatePipeline(new HttpControllerDispatcher(config), handlers);
// configure route
config.Routes.MapHttpRoute("DefaultRoute",
"{controller}/{id}",
new {id = RouteParameter.Optional},
null,
routeHandlers);
/* other settings (JSON formatting, ...) */
/* dependency resolver, which will pass an instance of my DAO factory to each controller */
config.DependencyResolver = new ControllerDependencyResolver(daoFactory);
/* apply CORS message handler to all messges */
config.MessageHandlers.Add(new CorsHandler());
如果我通过 AJAX 调用调用 Web API 方法,这需要身份验证(例如“127.0.0.1:80/test/id”),一切都会按预期工作。消息处理程序将被调用,如下所示:
有效的用户凭据:
客户端 -> CorsHandler -> HmacAuthenticationHandler -> TestController (get(id)) -> CorsHandler -> HmacAuthenticationHandler -> 客户端 (OK-200)
无效的用户凭据:
客户端 -> CorsHandler -> HmacAuthenticationHandler -> CorsHandler -> HmacAuthenticationHandler -> 客户端(未经授权的请求 403)
但是,如果我通过 AJAX 调用调用不需要身份验证的 Web API 方法(例如“127.0.0.1:80/login”)。HmacAuthenticationHandler 将在“返回客户端的路上”被调用,即使它没有分配给这个路由:
客户端 -> CorsHandler -> AccountController(登录) -> CorsHandler -> HmacAuthenticationHandler -> 客户端 (OK-200)
为什么会在HmacAuthenticationHandler
“公共路线”上(响应期间)被调用?奇怪的是它不会影响响应,客户端仍然得到 OK-200。
更新
我创建了一个示例项目并用假的替换了所有内部接口/实现,可以在 BitBucket 上找到并下载代码: