简体   繁体   English

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

[英]WCF sessions with a wsHttpBinding and without windows security

I need to create a WCF service that is hosted in IIS, uses http transport and hold state in the server's memory. 我需要创建一个托管在IIS中的WCF服务,使用http传输并在服务器的内存中保存状态。 While I'm aware that stateful services aren't a good idea, this last constrain is necessary to make the service work with a legacy client. 虽然我知道有状态服务并不是一个好主意,但最后的约束对于使服务与传统客户端一起工作是必要的。

My first thought was to asp.net's session to store the values. 我的第一个想法是asp.net的会话来存储值。 I activated the asp.net compatibility mode in my service, which gave me access to the HttpContext, but values that were placed in the session object were not being persisted in memory. 我在我的服务中激活了asp.net兼容模式,这使我可以访问HttpContext,但是放在会话对象中的值没有被保存在内存中。 I assume this was because the http module that handles session state was not correctly configured, but when googling for answer I came across, WCF sessions and thought it might be a better idea to use them. 我认为这是因为处理会话状态的http模块没有正确配置,但是当我在网上搜索得到答案时,WCF会话并认为使用它们可能是个更好的主意。

However, WCF sessions seem what under-document and place a strange set of prerequises on a service, and I haven't been able to find a configuration that suits my needs: must be hosted in IIS, must use http or https transport and can't reply on windows authentication because the client and server will not be part of the same domain. 但是,WCF会话似乎是在文档下面并在服务上放置了一组奇怪的先决条件,而且我无法找到适合我需要的配置:必须在IIS中托管,必须使用http或https传输并且可以不回复Windows身份验证,因为客户端和服务器不属于同一个域。 I'm trying to get this going using the wsHttpBinding, I had heard WCF sessions required either security or reliable message, but: - Using the standard binding and when the servers are not part of the same domain it fails with a “SecurityNegotiationException The caller was not authenticated by the service” exception. 我试图使用wsHttpBinding来实现这一点,我听说过WCF会话需要安全性或可靠的消息,但是: - 使用标准绑定,当服务器不属于同一个域时,它会失败并出现“SecurityNegotiationException调用者没有通过服务“例外验证。 This is fairly logical as it was using windows security. 这是相当合理的,因为它使用的是Windows安全性。

  • If I disable security complete it fails with a “Contract requires Session, but Binding 'WSHttpBinding' doesn't support it or isn't configured properly to support it.” 如果我禁用安全性完成,它将失败并显示“合同需要会话,但绑定'WSHttpBinding'不支持它或未正确配置以支持它。”

  • If while keeping security disabled I enable reliable message I get the exception “Binding validation failed because the WSHttpBinding does not support reliable sessions over transport security (HTTPS). 如果在保持安全性被禁用的同时启用可靠消息,我会收到异常“绑定验证失败,因为WSHttpBinding不支持基于传输安全性的可靠会话(HTTPS)。 The channel factory or service host could not be opened. 无法打开通道工厂或服务主机。 Use message security for secure reliable messaging over HTTP.” 使用消息安全性实现HTTP上安全可靠的消息传递。“

  • I've tried enabling transport level security but this doesn't seem to make any difference to the error generated 我已经尝试启用传输级安全性,但这似乎对生成的错误没有任何影响

Is there any configuration that might work for me? 有没有可能对我有用的配置? Or should I just go back to the plan of using asp.net sessions? 或者我应该回到使用asp.net会话的计划?

You can have WCF hold session information in memory in a pretty simple way. 您可以以非常简单的方式在内存中保存WCF会话信息。 To eliminate any possible external influences in my instructions, I'll assume you're starting with a brand new project: 为了消除我的指示中任何可能的外部影响,我假设您从一个全新的项目开始:

  1. Create a new WCF Service Library project. 创建一个新的WCF服务库项目。 This project will already contain a service with a WSHttpBiding binding preconfigured. 该项目已经包含一个预先配置了WSHttpBiding绑定的服务。
  2. Go to the service contract (IService1.cs) and change the ServiceContract attribute to the following: 转到服务合同(IService1.cs)并将ServiceContract属性更改为以下内容:

     [ServiceContract(SessionMode = SessionMode.Required)] 
  3. Go to the service implimentation (Service1.cs) and add the following ServiceBehavior attribute to the service class ( Service1 ): 转到服务实现(Service1.cs)并将以下ServiceBehavior属性添加到服务类( Service1 ):

     [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)] 
  4. Add session data as members of the service class ( Service1 ): 将会话数据添加为服务类( Service1 )的成员:

     public class Service1 : IService1 { ... private string UserFullName { get; set; } ... } 
  5. Use the members to present session specific data (remember to also add them to the service contract, IService1 ): 使用成员呈现会话特定数据(还记得将它们添加到服务合同中, 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"); } ... } 

SessionMode.Required ensures that your clients are session-tracked. SessionMode.Required确保您的客户端是会话跟踪的。
InstanceContextMode.PerSession ensures that an instance of your service class (Service1) is created for every session, so that you can retain session data in it and it will exist in memory across multiple calls in the same session. InstanceContextMode.PerSession确保为每个会话创建服务类(Service1)的实例,以便您可以在其中保留会话数据,并且它将存在于同一会话中多个调用的内存中。
ConcurrencyMode.Single ensures that only one thread can enter each service class instance (Service1), and prevents possible concurrency issues if you only access data from the service class (and external thread-safe locations). ConcurrencyMode.Single确保只有一个线程可以进入每个服务类实例(Service1),并且如果您只访问服务类(和外部线程安全位置)中的数据,则可以防止可能的并发问题。

EDIT: By default, WSHttpBinding only allows security sessions. 编辑:默认情况下, WSHttpBinding仅允许安全会话。 But it also support reliable sessions, which allow establishing sessions without security enabled. 但它也支持可靠的会话,允许在没有启用安全性的情况下建立会话。 The following binding configuration disables security and enables reliable sessions: 以下绑定配置会禁用安全性并启用可靠会话:

<wsHttpBinding>
    <binding name="wsHttpBindingConfiguration">
        <security mode="None" />
        <reliableSession enabled="true" />
    </binding>
</wsHttpBinding>

IMO this is what happens when you're using a technology with a poor abstraction over HTTP like WCF. IMO就是当你使用像WCF这样的HTTP抽象不佳的技术时会发生这种情况。 The fact that WCF web services could in theory be hosted without HTTP (ie over NET TCP, MSMQ, etc) just makes it hard to use built-in features of HTTP without entering in configuration hell and start a game of "guess the correct configuration by trial and error" where you try every possible configuration permutation until you've found the correct one that works! WCF Web服务理论上可以在没有HTTP的情况下托管(即通过NET TCP,MSMQ等),这使得很难使用HTTP的内置功能而无需进入配置地狱并开始“猜测正确配置”的游戏通过反复试验“你在哪里尝试每一种可能的配置排列,直到你找到了正确的配置!

Ultimately if you couldn't use WCF and had to implement the web service from scratch you would simply set a cookie when the client successfully authenticated. 最终,如果您无法使用WCF并且必须从头开始实施Web服务,则只需在客户端成功通过身份验证后设置cookie。 Then with every client request just grab the session information referenced by that cookie. 然后,每个客户端请求只需获取该cookie引用的会话信息。

One possible solution if you had to use WCF is to take session management in your own hands (It's what I do when I'm unhappy with the effort required to get something to work) and have an explicit 'Session' property on all your web services that require a session/authentication (usually a guid generated on Authentication). 如果你不得不使用WCF,一个可能的解决方案就是自己动手进行会话管理(这是我在努力工作所需的努力时所做的事情)并且在你的所有网站上都有明确的“会话”属性需要会话/身份验证的服务(通常是在身份验证时生成的guid)。 So for each subsequent request you use the guid to rehydrate the session information associated with that client. 因此,对于每个后续请求,您都可以使用guid来重新水化与该客户端关联的会话信息。

If you're interested in trying out different web service frameworks I maintain an Open Source Web Services Framework that lets you build configuration-free, DRY, testable web services where (without any configuration required) each web service you create is automatically accessible over REST XML, JSON, JSV, SOAP 1.1, SOAP 1.2 endpoints. 如果您对尝试不同的Web服务框架感兴趣,我会维护一个开源Web服务框架 ,该框架允许您构建无配置,干燥,可测试的Web服务,其中(无需任何配置)您创建的每个Web服务都可以通过REST自动访问XML,JSON,JSV,SOAP 1.1,SOAP 1.2端点。 Effectively it allows you to access your same web service via a HTTP GET url for REST-ful clients and easy debugging as well as SOAP endpoints (a popular choice still mandated by some enterprises). 实际上,它允许您通过HTTP GET URL访问相同的Web服务,以便REST-ful客户端和简单的调试以及SOAP端点(一些企业仍然强制要求的流行选择)。 The Hello World tutorial should give you a good overview on some of its features and how it works. Hello World教程应该为您提供有关其一些功能及其工作原理的概述。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM