使用OWIN添加多个WWW-Authenticate标头

时间:2014-03-07 14:49:13

标签: http authentication asp.net-web-api restful-authentication katana

我希望我们的服务能够宣传多种身份验证方案:例如Bearer和一些自定义方案,比如X-Custom。 (我为每个方案都有一个OWIN中间件组件)。我从RFC 2616, sec 14.47开始,有多种方法可以做到:

选项a)多个标头 WWW-Authenticate: Bearer WWW-Authenticate: X-Custom

选项b)以逗号分隔的列表 WWW-Authenticate: Bearer, X-Custom

我的偏好是选项a)因此客户端只需执行类似Response.Headers.Exists("WWW-Authenticate", preferredScheme)的操作而不是逗号解析标题(RFC表示应该这样做,但是......)

然而,Katana使用字典作为标题。尝试添加第二个标题会引发一个异常,“密钥'WWW-Authenticate'已存在于字典中。”

中间件组件是否有办法注入多个WWW-Authenticate标头?

1 个答案:

答案 0 :(得分:3)

IDictionary<string, string[]>。 Key是一个字符串,但value是一个字符串数组。所以,你只需要像这样设置标题。

app.Run(async (IOwinContext context) =>
{
    context.Response.Headers.Add("WWW-Authenticate",
                                    new[] { "Bearer", "X-Custom" });
    // Some other code
});

UPDATE 我相信你非常友好地接受我的回答:)。谢谢,但不确定它回答了你的问题,因此编辑。首先,我没有得到你试图提出的观点,即从不同的中间件添加不同的标题,但又希望在响应中的不同行中看到它们。对于像WWW-Authenticate这样的标准HTTP头,我认为无论如何都不会这样做。事实上,在我回答你的问题之前,我很快写了一个小程序来验证,但我犯的错误是拼错了这个标题。  因此,我实际上得到了这样的标题值。

WWW-Authentciate: X-Custom
WWW-Authentciate: Bearer

无论如何,以下方法可以将标题值分为两行。

app.Use(async (IOwinContext context, Func<Task> next) =>
{
    context.Response.Headers.Set("WWW-Authenticate", "Bearer");

    await next.Invoke();
});

app.Run(async (IOwinContext context) =>
{
    var x = context.Response.Headers.Get("WWW-Authenticate");
    context.Response.Headers.Remove("WWW-Authenticate");
    context.Response.Headers.Add("WWW-Authenticate", new[] { "X-Custom", x });
});

但是,这对标准标题不起作用。尽管如此,这是一个有趣的练习,但在一天结束时,这里的API没有公认的标准(据我所知)。即使你以某种方式让它按照你想要的方式工作,当你改变一个底层的OWIN组件,比如服务器或主机时,你可能会得到不同的行为。毕竟,选项a和选项b完全相同,如果你正在某个库的顶部工作来读取标题,你应该看不出任何区别,除非你做了一些低级的东西。

相关问题