簡體   English   中英

使用wsHttpBinding並且沒有Windows安全性的WCF會話

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

我需要創建一個托管在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會話的計划?

您可以以非常簡單的方式在內存中保存WCF會話信息。 為了消除我的指示中任何可能的外部影響,我假設您從一個全新的項目開始:

  1. 創建一個新的WCF服務庫項目。 該項目已經包含一個預先配置了WSHttpBiding綁定的服務。
  2. 轉到服務合同(IService1.cs)並將ServiceContract屬性更改為以下內容:

     [ServiceContract(SessionMode = SessionMode.Required)] 
  3. 轉到服務實現(Service1.cs)並將以下ServiceBehavior屬性添加到服務類( Service1 ):

     [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)] 
  4. 將會話數據添加為服務類( Service1 )的成員:

     public class Service1 : IService1 { ... private string UserFullName { get; set; } ... } 
  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"); } ... } 

SessionMode.Required確保您的客戶端是會話跟蹤的。
InstanceContextMode.PerSession確保為每個會話創建服務類(Service1)的實例,以便您可以在其中保留會話數據,並且它將存在於同一會話中多個調用的內存中。
ConcurrencyMode.Single確保只有一個線程可以進入每個服務類實例(Service1),並且如果您只訪問服務類(和外部線程安全位置)中的數據,則可以防止可能的並發問題。

編輯:默認情況下, WSHttpBinding僅允許安全會話。 但它也支持可靠的會話,允許在沒有啟用安全性的情況下建立會話。 以下綁定配置會禁用安全性並啟用可靠會話:

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

IMO就是當你使用像WCF這樣的HTTP抽象不佳的技術時會發生這種情況。 WCF Web服務理論上可以在沒有HTTP的情況下托管(即通過NET TCP,MSMQ等),這使得很難使用HTTP的內置功能而無需進入配置地獄並開始“猜測正確配置”的游戲通過反復試驗“你在哪里嘗試每一種可能的配置排列,直到你找到了正確的配置!

最終,如果您無法使用WCF並且必須從頭開始實施Web服務,則只需在客戶端成功通過身份驗證后設置cookie。 然后,每個客戶端請求只需獲取該cookie引用的會話信息。

如果你不得不使用WCF,一個可能的解決方案就是自己動手進行會話管理(這是我在努力工作所需的努力時所做的事情)並且在你的所有網站上都有明確的“會話”屬性需要會話/身份驗證的服務(通常是在身份驗證時生成的guid)。 因此,對於每個后續請求,您都可以使用guid來重新水化與該客戶端關聯的會話信息。

如果您對嘗試不同的Web服務框架感興趣,我會維護一個開源Web服務框架 ,該框架允許您構建無配置,干燥,可測試的Web服務,其中(無需任何配置)您創建的每個Web服務都可以通過REST自動訪問XML,JSON,JSV,SOAP 1.1,SOAP 1.2端點。 實際上,它允許您通過HTTP GET URL訪問相同的Web服務,以便REST-ful客戶端和簡單的調試以及SOAP端點(一些企業仍然強制要求的流行選擇)。 Hello World教程應該為您提供有關其一些功能及其工作原理的概述。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM