使用wsHttpBinding并且没有Windows安全性的WCF会话

Rob*_*ert 11 .net wcf wcf-binding wcf-security wcf-sessions

我需要创建一个托管在IIS中的WCF服务,使用http传输并在服务器的内存中保存状态.虽然我知道有状态服务并不是一个好主意,但最后的约束对于使服务与传统客户端一起工作是必要的.

我的第一个想法是asp.net的会话来存储值.我在我的服务中激活了asp.net兼容模式,这使我可以访问HttpContext,但是放在会话对象中的值没有被保存在内存中.我认为这是因为处理会话状态的http模块没有正确配置,但是当我在网上搜索答案时,WCF会话并认为使用它们可能更好.

但是,WCF会话似乎是在文档下面并在服务上放置了一组奇怪的先决条件,而且我无法找到适合我需要的配置:必须在IIS中托管,必须使用http或https传输并且可以不回复Windows身份验证,因为客户端和服务器不属于同一个域.我试图使用wsHttpBinding来实现这一点,我听说过WCF会话需要安全性或可靠的消息,但是: - 使用标准绑定,当服务器不属于同一个域时,它会失败并出现"SecurityNegotiationException调用者没有通过服务"例外验证.这是相当合理的,因为它使用的是Windows安全性.

  • 如果我禁用安全性完成,它将失败并显示"合同需要会话,但绑定'WSHttpBinding'不支持它或未正确配置以支持它."

  • 如果在保持安全性被禁用的同时启用可靠消息,我会收到异常"绑定验证失败,因为WSHttpBinding不支持基于传输安全性的可靠会话(HTTPS).无法打开通道工厂或服务主机.使用消息安全性实现HTTP上安全可靠的消息传递."

  • 我已经尝试启用传输级安全性,但这似乎对生成的错误没有任何影响

有没有可能对我有用的配置?或者我应该回到使用asp.net会话的计划?

All*_*nek 25

您可以以非常简单的方式在内存中保存WCF会话信息.为了消除我的指示中任何可能的外部影响,我假设您从一个全新的项目开始:

  1. 创建一个新的WCF服务库项目.此项目已包含WSHttpBiding具有预配置绑定的服务.
  2. 转到服务合同(IService1.cs)并将ServiceContract属性更改为以下内容:

    [ServiceContract(SessionMode = SessionMode.Required)]
    
    Run Code Online (Sandbox Code Playgroud)
  3. 转到服务实现(Service1.cs)并将以下ServiceBehavior属性添加到服务类(Service1):

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
    
    Run Code Online (Sandbox Code Playgroud)
  4. 将会话数据添加为服务类(Service1)的成员:

    public class Service1 : IService1
    {
        ...
    
        private string UserFullName { get; set; }
    
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 使用成员显示会话特定数据(还记得将它们添加到服务合同中IService1):

    public class Service1 : IService1
    {
        ...
    
        public string Welcome(string fullName)
        {
            UserFullName = fullName ?? "Guest";
            return string.Format("Welcome back, {0}!", UserFullName);
        }
    
        public string Goodbye()
        {
            return string.Format("Come back soon, {0}!", UserFullName ?? "Guest");
        }
    
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

SessionMode.Required确保您的客户端被会话跟踪.
InstanceContextMode.PerSession确保为每个会话创建服务类(Service1)的实例,以便您可以在其中保留会话数据,并且它将存在于同一会话中多个调用的内存中.
ConcurrencyMode.Single确保只有一个线程可以进入每个服务类实例(Service1),并且如果您只访问服务类(和外部线程安全位置)中的数据,则可以防止可能的并发问题.

编辑:默认情况下,WSHttpBinding仅允许安全会话.但它也支持可靠的会话,允许在没有启用安全性的情况下建立会话.以下绑定配置会禁用安全性并启用可靠会话:

<wsHttpBinding>
    <binding name="wsHttpBindingConfiguration">
        <security mode="None" />
        <reliableSession enabled="true" />
    </binding>
</wsHttpBinding>
Run Code Online (Sandbox Code Playgroud)