如何在 WCF 服务的所有后续 HTTP 请求标头中获取身份验证 cookie?
我在将身份验证 cookie 放入使用“会话”的 IIS 中托管的 WCF 服务的客户端 Windows 服务的 HTTP 请求标头中时遇到问题。客户端应用程序使用表单身份验证来访问 WCF 服务。身份验证成功后,我捕获 HTTP 响应标头,其中包含 .ASPXAUTH 的 Set-Cookie 和 ASP.NET_SessionId 的 Set-Cookie。我将这些 cookie 添加到 WCF 服务的所有后续请求的 HTTP 请求标头中。使用 Fiddler 调试工具,我可以看到对于 WCF 服务的每个请求,都会发送两个 HTTP 请求。第一个 HTTP 请求标头不包含 cookie,但第二个 HTTP 请求包含。当我通过将 web.config 的授权部分设置为“拒绝用户 =”?”' 来保护服务时,标头中没有 cookie 的第一个 HTTP 请求会强制“重定向”回登录状态,从而阻止访问该服务。我认为第一个请求与“会话”的使用有关。当我在 WCF 服务中禁用“会话”时,每个 WCF 调用仅收到一个 HTTP 请求,并且 cookie 位于标头中。如何在发送到我的 WCF 服务的所有 HTTP 请求标头中获取从身份验证返回的 cookie? 任何有关此问题的帮助将不胜感激。
我已经包含了来自客户端的绑定。
<customBinding>
<binding name="CustomBinding_IMySyncService" receiveTimeout="00:01:00"
sendTimeout="00:01:00">
<reliableSession acknowledgementInterval="00:00:30"
inactivityTimeout="00:03:00"
maxTransferWindowSize="4096" />
<binaryMessageEncoding maxReadPoolSize="2147483647" maxWritePoolSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binaryMessageEncoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
<binding name="CustomBinding_AuthenticationService">
<binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binaryMessageEncoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
I am having troubles getting authentication cookies placed into the HTTP Request Headers of a client Windows Service consuming a WCF Service hosted in IIS that is using ‘Sessions’. The client app uses Forms Authentication to gain access to the WCF Service. After a successful Authentication, I capture the HTTP Response header contains a Set-Cookie for .ASPXAUTH and a Set-Cookie for ASP.NET_SessionId. I add these cookies to the HTTP Request header for all subsequent requests to the WCF Service. Using the Fiddler debugging tool I can see that for every request to the WCF service, two HTTP Requests are sent. The first HTTP Request header does not contain the cookies but the second HTTP Request does. When I secure the service by setting the Authorization section of the web.config to ‘deny users=”?”’, the first HTTP Request without the cookies in the header forces a ‘Redirect’ back to login preventing access to the service. The first request I believe to be related to the use of ‘Sessions’. When I disable ‘Sessions’ in my WCF Service, I get only one HTTP Request per WCF call and the cookies are in the header. How do I get the cookies returned from Authentication in all of the HTTP Request headers sent to my WCF Service?
Any help with this issue would be very much appreciated.
I have included my bindings from the client.
<customBinding>
<binding name="CustomBinding_IMySyncService" receiveTimeout="00:01:00"
sendTimeout="00:01:00">
<reliableSession acknowledgementInterval="00:00:30"
inactivityTimeout="00:03:00"
maxTransferWindowSize="4096" />
<binaryMessageEncoding maxReadPoolSize="2147483647" maxWritePoolSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binaryMessageEncoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
<binding name="CustomBinding_AuthenticationService">
<binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binaryMessageEncoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我猜您所说的会话是指绑定中允许的可靠会话。可靠会话发送不受您控制的基础设施消息。修改该行为需要对 WCF 通道堆栈的非常低级别进行一些修改。
如果您想使用由 cookie 处理的 ASP.NET 会话,则必须使用 ASP.NET 兼容模式。即使具有 ASP.NET 兼容性,WCF 也不认为身份验证将由 cookie 处理 - 正确的方法是对每个请求进行身份验证。默认情况下,WCF 根本不使用 cookie。
ASP.NET 兼容模式应该与普通 Web 服务一起使用 - 作为与旧 ASMX Web 服务的向后兼容性。因此它不必与 WS-Reliable Session 等更高级的协议一起使用。使用可靠会话或 ASP.NET 兼容性 - 但不能同时使用两者。
使用可靠会话后,您已经拥有 WCF 会话(单个服务实例处理来自同一客户端代理实例的所有请求),因此您不需要 ASP.NET 会话。如果您使用内置 WCF 安全管道,则代理应在每条消息中自动发送身份验证凭据。
I guess by session you mean reliable session allowed in your binding. Reliable session sends infrastructure messages which are out of your control. The modifying that behavior with demand some modification on very low level of WCF channel stack.
If you want to use ASP.NET session handled by cookies you have to use ASP.NET compatibility mode. Even with ASP.NET compatibility WCF doesn't suppose that authentication will be handled by cookies - the correct way is authenticating each request. WCF also by default doesn't use cookies at all.
ASP.NET compatibility mode is supposed to be used with plain web services - as backward compatibility with old ASMX web services. So it doesn't have to work with more advanced protocols like WS-Reliable Session. Use either reliable session or ASP.NET compatibility - not both.
Once you are using reliable session you already have WCF session (the single service instance handles all request from the same client proxy instance) so you don't need ASP.NET session. If you use built-in WCF security pipeline authentication credentials should be send by the proxy automatically within each message.