我无法弄清楚如何在使用HTTPS时为我的WCF服务启用每会话实例。 (我不是ASP.NET专家,但如果可能的话,不想使用ASP.NET会话状态。)我正在使用.NET Framework 3.0。
我已经遇到了以下矛盾,我希望有人可以告诉我逻辑中存在缺陷。
1)由于客户授权,该服务必须托管在IIS 6上。
2)服务需要在调用之间维护状态,包括SqlConnection和SqlTransaction实例(由于项目限制,丑陋但必要)。
3)因此我需要使用wsHttpBinding。
4)服务需要能够从HttpContext.Current.User.Identity访问用户身份验证信息(例如,在IIS中使用Windows安全性)。
5)因此需要HTTPS。
6)因此必须在绑定上配置传输级安全性。
7)将服务配置为需要会话意味着我必须配置wsHttpBinding以使用可靠会话。
8)这要求在绑定上配置消息级安全性。
即。 (6)和(8)是相互排斥的。
似乎使用WCF会话要求我使用消息级安全性,这会阻止我使用HTTPS。
我错过了什么?
答案 0 :(得分:15)
3) True , wsHttpBinding 和 wsDualHttpBinding 是唯一支持会话的HTTP绑定
5) False ,为了验证服务调用者,您不一定需要具有任何传输级安全性(例如SSL / HTTPS)。唯一的要求是配置IIS以为虚拟目录启用集成Windows身份验证。然后在WCF中,您有三种可能性来启用此方案:
a)使用Windows凭据(HTTPS)在wsHttpBinding上使用传输级安全性
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="SecurityEnabledWsHttp">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
b)在带有Windows凭据(HTTP)的wsHttpBinding上使用消息级安全性
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="SecurityEnabledWsHttp">
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
c)在 ASP.NET兼容模式下运行您的服务,并在ASP.NET(HTTP)中启用 Windows身份验证
<system.web>
<authentication mode="Windows" />
</system.web>
请注意,在 a 和 b 中,您将以这种方式从服务中访问来电者的身份:
OperationContext.Current.ServiceSecurityContext.WindowsIdentity
6) True ,必须在wsHttpBinding上启用传输级安全性才能使用HTTPS
7)错误,可靠会话是WCF会话的可靠消息传递的特定实现。可靠消息传递是一种WS- *标准规范,旨在保证在不可靠的网络上传递消息。您可以在没有Reliable Messaging的情况下使用WCF会话,反之亦然。使用此属性在服务合同上启用会话:
[ServiceContract(SessionMode=SessionMode.Required)]
public interface IMyService {
// ...
}
还要记住,为了在服务调用之间维护状态,您将明确地必须在服务契约实现上启用适当的实例模式:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MyService : IMyService {
// ...
}
WCF中有两种会话:安全会话和可靠会话。 wsHttpBinding 和 netTcpBinding 的默认设置是使用安全会话。
对于wsHttpBinding,这是通过消息级安全性来实现的。使用客户端的凭据,即绑定的默认设置。
对于netTcpBinding,会话通过使用设施的设施在传输级建立 TCP协议。
这意味着只需切换到wsHttpBinding或netTcpBinding就可以支持WCF会话
另一种方法是使用可靠会话。这必须在绑定配置中明确启用,并消除了对wsHttpBinding使用消息安全性的要求。所以这将有效:
<bindings>
<wshttpbinding>
<binding name="ReliableSessionEnabled">
<reliablesession enabled="True" ordered="False" />
<security mode="None" />
</binding>
</wshttpbinding>
</bindings>
8)错误,可靠会话的使用与通信渠道的安全设置无关。
有关更详细的说明,请查看this article。
答案 1 :(得分:2)
继Enrico的优秀答案之后,这些是我正在使用的配置:
服务:
<services>
<service name="Foo.Bar.Service">
<endpoint name="EndpointHttps"
address=""
binding="customBinding" bindingConfiguration="EndpointHttps"
contract="Foo.Bar.IService" />
</service>
</services>
<bindings>
<customBinding>
<binding name="EndpointHttps">
<reliableSession />
<mtomMessageEncoding />
<httpsTransport />
</binding>
</customBinding>
</bindings>
客户端:
<client>
<endpoint name="EndpointHttps"
address="https://server/FooBar/service.svc"
binding="customBinding" bindingConfiguration="EndpointHttps"
contract="Foo.Bar.IService" />
</client>
<bindings>
<customBinding>
<binding name="EndpointHttps">
<reliableSession />
<mtomMessageEncoding />
<httpsTransport />
</binding>
</customBinding>
</bindings>
注意:尽管如此,仍然没有使用Windows身份验证。