【问题标题】:IIS dumps Authorization header on redirect after WCF service call without trailing slashIIS 在 WCF 服务调用后在重定向时转储授权标头而不使用斜杠
【发布时间】:2011-08-08 18:03:19
【问题描述】:

我正在组合一个在 IIS 7 网站实例中运行的 WCF REST 服务,并且我正在使用 HMAC 身份验证方案,该方案将令牌和 HMAC 插入到身份验证标头中。典型请求的示例标头列表可能如下所示:

GET http://api.mydomain.com/Contacts HTTP/1.1
Authorization: 774F035C-FRTB-4207-DDDD-31BF1534AD96:9h0Whke9Bgi3XSHPo/YSXw==
Content-Type: application/xml; charset=utf-8
Host: api.mydomain.com
Connection: Keep-Alive

我使用路由而不是 .svc 文件设置了服务,所以我的 Global.asax 看起来像这样:

    protected void Application_Start(object sender, EventArgs e)
    {
        RouteTable.Routes.Add(new ServiceRoute("Users", new WebServiceHostFactory(), typeof(UsersService)));
        RouteTable.Routes.Add(new ServiceRoute("Widgets", new WebServiceHostFactory(), typeof(WidgetsService)));
    }

问题在于,当使用这样的路由声明服务时,如果 IIS 收到对 WebGet uri 没有尾部斜杠的调用,它会执行 307 重定向到 uri 带有一个斜杠。您会认为这很有帮助,但问题是重定向转储了 Authorization 标头。

我的服务课程都是犹太洁食,在其他各个方面都表现出色。 有没有办法让我能够在发生重定向时维护授权标头?我怀疑解决方案将是一个 IIS 配置问题,但我想我可以把所有各种路由黑客来获取 uri 的无斜线版本。

更新:
我发现 this article 验证了这种行为,但并没有真正给出任何修复。

【问题讨论】:

    标签: wcf rest iis-7 hmac


    【解决方案1】:

    所以我不完全确定 IIS 为何会卷入其中。当您说“转储授权标头”时,您是什么意思?你的意思是它作为重定向的一部分重新发送它还是不发送它?

    WCF 明智的做法是,您可能会阻止重定向发生。这是您想要在微软几乎做对的事情之一。 UriTemplate 类本身可以通过恰当命名的 IgnoreTrailingSlash property 忽略斜杠。不幸的是,WCF WebInvoke/Get 属性实际上并没有以任何方式映射此属性,因此始终创建的模板完全绑定到您在 UriTemplate 属性中键入的任何内容。

    因此,最简单的解决方法是重载 WCF 合同上的方法,并使用带有斜杠的第二个签名。例如:

    [OperationContract]
    [WebGet(UriTemplate="/Users")]
    public List<User> GetUsers()
    {
       .... some code here ...
    }
    
    [OperationContract]
    [WebGet(UriTemplate="/Users/")]
    public List<User> GetUsersSlash()
    {
       return this.GetUsers();
    }
    

    丑陋,对吧?如果这是您想要一遍又一遍地重复的模式,则尤其糟糕。所以另一个半但不那么hacky的选项是编写自定义操作选择器逻辑,您可以通过自定义行为将其应用于您的服务。在this StackOverflow answer 中有更多关于执行此操作的详细信息。

    【讨论】:

    • 感谢您的回复。要回答您的第一个问题,IIS 不会将其作为重定向的一部分重新发送。查看我添加到原始帖子中的文章,这似乎是设计使然——根据 MS 的想法是授权应该再次发生。
    • 是的,好的,我完全理解这一点,但我不清楚这是否正是发生在你身上的事情。那么让我们退后一步,您是客户端还是其他不受您控制的应用程序是此服务的客户端?为什么不首先请求正确的 URL?您的服务被定义为没有斜杠,所以......这就是您的客户应该要求的。可以提出应该允许尾部斜杠的论点,但从技术上讲,不断重定向请求是浪费带宽,因为最终,它不是同一个 URL。
    • 其他不受我控制的应用程序将是客户端。我真的没有需要尾部斜杠的问题,因为它无论如何都更加 RESTful,但我不希望错误消息是 401 Unauthorized。我宁愿 404 他们或类似的东西。不幸的是,无论我指定的 UriTemplate 是什么,服务路由定义似乎都无法实现。
    • 原来这个解决方案似乎不起作用。更改 UriTemplate 以包含或排除斜线似乎不会改变重定向的构造方式。看起来 Authorization 标头的删除是设计使然。无赖。
    • 是的,我认为您无法通过在服务器端进行更改来解决此问题。我的建议是您在服务器端支持正确的 URL,并确保您的所有客户端都访问该 URL,以便没有重定向。
    猜你喜欢
    • 1970-01-01
    • 2012-09-04
    • 2017-06-24
    • 1970-01-01
    • 2021-05-21
    • 2013-05-18
    • 1970-01-01
    • 2019-02-12
    • 2020-10-15
    相关资源
    最近更新 更多