2012-09-25 12 views
13

में एसएसएल wsHttp बाइंडिंग के साथ सत्र को कैसे सक्षम करें मेरे पास wsHttp बाइंडिंग और एसएसएल सक्षम के साथ एक डब्ल्यूसीएफ सेवा है, लेकिन मैं डब्ल्यूसीएफ सत्र सक्षम करना चाहता हूं।डब्ल्यूसीएफ

आवश्यक

SessionMode:=SessionMode.Required 

को SessionMode बदलने के बाद मैं त्रुटि नीचे वर्णित हो रही है।

अनुबंध सत्र की आवश्यकता है, लेकिन बाध्यकारी 'WSHttp बाइंडिंग' का समर्थन नहीं करता है या इसे समर्थन देने के लिए ठीक से कॉन्फ़िगर नहीं किया गया है।

यहां मेरा नमूना आवेदन है।

App.config

<?xml version="1.0" encoding="utf-8" ?> 
    <configuration> 

     <system.web> 
     <compilation debug="true" /> 
     </system.web> 
     <!-- When deploying the service library project, the content of the config file must be added to the host's 
     app.config file. System.Configuration does not support config files for libraries. --> 
     <system.serviceModel> 

     <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
     <client /> 
     <bindings> 
      <wsHttpBinding> 
      <binding name="NewBinding0" useDefaultWebProxy="false" allowCookies="true"> 
       <readerQuotas maxStringContentLength="10240" /> 
       <!--reliableSession enabled="true" /--> 
       <security mode="Transport"> 
       <transport clientCredentialType="None" proxyCredentialType="None" > 
        <extendedProtectionPolicy policyEnforcement="Never" /> 
       </transport > 
       </security> 
      </binding> 
      </wsHttpBinding> 
     </bindings> 
     <services> 
      <service name="WcfServiceLib.TestService"> 
      <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NewBinding0" 
       contract="WcfServiceLib.ITestService"> 
       <identity> 
       <servicePrincipalName value="Local Network" /> 
       </identity> 
      </endpoint> 
      <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" /> 
      <host> 
       <baseAddresses> 
       <add baseAddress="https://test/TestService.svc" /> 
       </baseAddresses> 
      </host> 
      </service> 
     </services> 

     <behaviors> 
      <serviceBehaviors> 
      <behavior> 
       <!-- To avoid disclosing metadata information, 
       set the value below to false and remove the metadata endpoint above before deployment --> 
       <serviceMetadata httpsGetEnabled="True"/> 
       <!-- To receive exception details in faults for debugging purposes, 
       set the value below to true. Set to false before deployment 
       to avoid disclosing exception information --> 
       <serviceDebug includeExceptionDetailInFaults="False" /> 
      </behavior> 
      </serviceBehaviors> 
     </behaviors> 
     </system.serviceModel> 

    </configuration> 

ITestService.vb

<ServiceContract(SessionMode:=SessionMode.Required)> 
    Public Interface ITestService 

     <OperationContract(IsInitiating:=True, IsTerminating:=False)> _ 
     Function GetData(ByVal value As Integer) As String 

    End Interface 

TestService.vb

<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession, _ 
    ReleaseServiceInstanceOnTransactionComplete:=False, _ 
    ConcurrencyMode:=ConcurrencyMode.Single)> 
     Public Class TestService 
      Implements ITestService 

      Private _user As User 

      <OperationBehavior(TransactionScopeRequired:=True)> 
      Public Function GetData(ByVal value As Integer) As String _ 
Implements ITestService.GetData 

       If _user Is Nothing Then 

        _user = New User() 
        _user.userName = "User_" & value 
        _user.userPassword = "Pass_" & value 

        Return String.Format("You've entered: {0} , Username = {1} , Password = {2} ", _ 
             value, _user.userName, _user.userPassword) 
       Else 
        Return String.Format("Username = {1} , Password = {2} ", _ 
            _user.userName, _user.userPassword) 
       End If 

      End Function 

     End Class 

मैं सभी पो की कोशिश की ssible समाधान, मैं पा सकता था, लेकिन कुछ भी मदद की।

विश्वसनीय सत्र सक्षम करने के लिए कुछ सलाह है, लेकिन यह ssl साथ काम नहीं करता है (यदि केवल आप अपने कस्टम बाध्यकारी है), दूसरों को सलाह http बजाय https उपयोग करने के लिए है, लेकिन मैं था मेरे मौजूदा कॉन्फ़िगरेशन के साथ सत्र सक्षम करने की तरह, यदि यह संभव है।

क्या यह प्राप्त करने के लिए कोई दृष्टिकोण है?

किसी भी प्रकार की सहायता की बहुत सराहना की जाती है।

+0

डब्ल्यूसीएफ सेवा पर सत्र स्थिति को सक्षम करने का क्या कारण है? यदि आप उच्च प्रदर्शन की तलाश में हैं तो यह एक बाधा हो सकती है। सत्र राज्य डब्ल्यूसीएफ सेवा से बचा जाना चाहिए। –

+0

मैं प्रत्येक सत्र के लिए _user चर होना चाहता हूं। मुझे प्रत्येक कॉल के लिए सेवा कक्षा का एक नया उदाहरण मिलता है। _user का मूल्य हमेशा कुछ भी नहीं है। – hgulyan

+0

यदि मुझे प्रत्येक ग्राहक के लिए डेटा स्टोर करने की आवश्यकता है, तो मुझे अपनी स्थिति के लिए किस समाधान का उपयोग करना चाहिए? – hgulyan

उत्तर

18

यदि आप wsHttp बाइंडिंग के साथ "सत्र" चाहते हैं, तो आपको या तो विश्वसनीय संदेश या सुरक्षा सत्र का उपयोग करना होगा। (स्रोत: how to enable WCF Session with wsHttpBidning with Transport only Security)।

WSHttp बाइंडिंग सत्र का समर्थन करता है, लेकिन केवल अगर सुरक्षा (सुरक्षित रूपांतरण) या विश्वसनीय संदेश सक्षम हैं। यदि आप परिवहन सुरक्षा का उपयोग कर रहे हैं तो यह WS-SecureConversation और WS-ReliableMessaging का उपयोग नहीं कर रहा है डिफ़ॉल्ट रूप से बंद कर दिया गया है। इसलिए सत्र के लिए WSHttp बाइंडिंग का उपयोग करने वाले दो प्रोटोकॉल उपलब्ध नहीं हैं। आपको या तो संदेश सुरक्षा का उपयोग करने या विश्वसनीय सत्र चालू करने की आवश्यकता है। (स्रोत: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/57b3453e-e7e8-4875-ba23-3be4fff080ea/)।

हमने मानक बाइंडिंग में एचटीपीएस पर आरएम को अस्वीकार कर दिया है क्योंकि आरएम सत्र को सुरक्षित करने का तरीका सुरक्षा सत्र का उपयोग करना है और एचटीपीएस सत्र प्रदान नहीं करता है।

मुझे इसके बारे में msdn blurb मिला: http://msdn2.microsoft.com/en-us/library/ms733136.aspx ब्लर्ब "एचटीटीपीएस का उपयोग करते समय एकमात्र अपवाद है। एसएसएल सत्र विश्वसनीय सत्र से बंधे नहीं है। यह एक खतरा लगाता है क्योंकि एक सुरक्षा संदर्भ साझा करने वाले सत्र (एसएसएल सत्र) एक-दूसरे से सुरक्षित नहीं हैं; यह एप्लिकेशन के आधार पर वास्तविक खतरा हो सकता है या नहीं। "

हालांकि यदि आप निर्धारित करते हैं कि कोई खतरा नहीं है तो आप इसे कर सकते हैं। कस्टम बाइंडिंग http://msdn2.microsoft.com/en-us/library/ms735116.aspx (स्रोत: http://social.msdn.microsoft.com/forums/en-US/wcf/thread/fb4e5e31-e9b0-4c24-856d-1c464bd0039c/) के माध्यम से HTTPS नमूना पर एक आरएम है।

अपने संभावनाओं संक्षेप में आप कर सकते हैं:

1 -, wsHttpBinding रखें परिवहन सुरक्षा हटाने और सक्षम विश्वसनीय संदेश

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

लेकिन आप ढीला अपनी सुरक्षा के एसएसएल परत और फिर भाग ।

2 -, wsHttpBinding रखें परिवहन सुरक्षा रखने के लिए और जोड़ने के संदेश प्रमाणीकरण

<wsHttpBinding> 
    <binding name="bindingConfig"> 
     <security mode="TransportWithMessageCredential"> 
     <message clientCredentialType="UserName"/> 
     </security> 
    </binding> 
    </wsHttpBinding> 

आप अपनी SSL सुरक्षा परत रखने के लिए मिलता है, लेकिन अपने ग्राहक (किसी भी रूप का) क्रेडेंशियल प्रदान करने के लिए है और होगा, भले ही आप उन्हें सेवा पक्ष में मान्य न करें, नकली लोगों को अभी भी प्रदान किया जाना चाहिए क्योंकि डब्ल्यूसीएफ किसी भी संदेश को अस्वीकार कर देगा जो प्रमाण-पत्र निर्दिष्ट नहीं करता है।

3 - एक कस्टम विश्वसनीय संदेश और HTTPS परिवहन के साथ बंधन

<customBinding> 
    <binding name="bindingConfig"> 
     <reliableSession/> 
     <httpsTransport/> 
    </binding> 
    </customBinding> 

मैं नहीं खतरा छोड़कर इस के लिए किसी भी नकारात्मक पक्ष यह देख सकते हैं MSDN में विस्तार से बताया उपयोग करें, और यह आपके आवेदन पर निर्भर करता है।

4 - अन्य सत्र प्रदाताओं उपयोग आपके आवेदन IIS में hotsed है, तो आप

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 

सेट और

HttpContext.Current.Session 
अपने राज्य के लिए

पर निर्भर कर सकता है।

या अपनी कुकीज़ को लागू करना।

पीएस: ध्यान दें कि उन सभी डब्ल्यूसीएफ कॉन्फ़िगरेशन के लिए, मैंने केवल सेवा सक्रियण का परीक्षण किया, कॉल नहीं।

संपादित करें: उपयोगकर्ता अनुरोध के अनुसार, wsHttpBindingTransportWithMessageCredential सुरक्षा मोड कार्यान्वयन सत्र के साथ (मैं वीबी से बहुत परिचित नहीं हूं।नेट तो मेरे वाक्य रचना क्षमा):

सेवा कोड का टुकड़ा:

<ServiceContract(SessionMode:=SessionMode.Required)> 
Public Interface IService1 

    <OperationContract()> _ 
    Sub SetSessionValue(ByVal value As Integer) 

    <OperationContract()> _ 
    Function GetSessionValue() As Nullable(Of Integer) 

End Interface 

<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession, 
    ConcurrencyMode:=ConcurrencyMode.Single)> 
Public Class Service1 
    Implements IService1 

    Private _sessionValue As Nullable(Of Integer) 

    Public Sub SetSessionValue(ByVal value As Integer) Implements IService1.SetSessionValue 
     _sessionValue = value 
    End Sub 

    Public Function GetSessionValue() As Nullable(Of Integer) Implements IService1.GetSessionValue 
     Return _sessionValue 
    End Function 
End Class 

Public Class MyUserNamePasswordValidator 
    Inherits System.IdentityModel.Selectors.UserNamePasswordValidator 

    Public Overrides Sub Validate(userName As String, password As String) 
     ' Credential validation logic 
     Return ' Accept anything 
    End Sub 

End Class 

सेवा विन्यास टुकड़ा:

<system.serviceModel> 
    <services> 
    <service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior"> 
     <endpoint address="" binding="wsHttpBinding" contract="WcfService1.IService1" bindingConfiguration="bindingConf"/> 
     <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/> 
    </service> 
    </services> 
    <bindings> 
    <wsHttpBinding> 
     <binding name="bindingConf"> 
     <security mode="TransportWithMessageCredential"> 
      <message clientCredentialType="UserName"/> 
     </security> 
     </binding> 
    </wsHttpBinding> 
    </bindings> 
    <behaviors> 
    <serviceBehaviors> 
     <behavior name="WcfService1.Service1Behavior"> 
     <serviceMetadata httpsGetEnabled="true"/> 
     <serviceDebug includeExceptionDetailInFaults="false"/> 
     <serviceCredentials> 
      <userNameAuthentication 
      userNamePasswordValidationMode="Custom" 
      customUserNamePasswordValidatorType="WcfService1.MyUserNamePasswordValidator, WcfService1"/> 
     </serviceCredentials> 
     </behavior> 
    </serviceBehaviors> 
    </behaviors> 
</system.serviceModel> 

क्लाइंट परीक्षण कोड का टुकड़ा:

Imports System.Threading.Tasks 

Module Module1 

    Sub Main() 
     Parallel.For(0, 10, Sub(i) Test(i)) 
     Console.ReadLine() 
    End Sub 

    Sub Test(ByVal i As Integer) 
     Dim client As ServiceReference1.Service1Client 
     client = New ServiceReference1.Service1Client() 
     client.ClientCredentials.UserName.UserName = "login" 
     client.ClientCredentials.UserName.Password = "password" 
     Console.WriteLine("Session N° {0} : Value set to {0}", i) 
     client.SetSessionValue(i) 
     Dim response As Nullable(Of Integer) 
     response = client.GetSessionValue() 
     Console.WriteLine("Session N° {0} : Value returned : {0}", response) 
     client.Close() 
    End Sub 

End Module 
+0

मेरे पास आपके समाधानों का परीक्षण करने के लिए समय नहीं है, 10 मिनट में बक्षीस समाप्त होता है, लेकिन यह उत्तर सबसे विस्तृत है, इसलिए मैं इसे स्वीकार करूंगा। यह कस्टम बाध्यकारी या TransportWithMessageCredential मोड का उपयोग करने के लिए मेरे लिए उपयुक्त है। मैं उन्हें दोनों कोशिश करूँगा। धन्यवाद। – hgulyan

+0

TransportWithMessageCredential wsHttp बाइंडिंग के साथ काम नहीं करेगा। यह केवल NetHttp बाइंडिंग के साथ काम करता है। Http://msdn.microsoft.com/en-us/library/ms730879.aspx – hgulyan

+0

देखें इसका मतलब है कि मेरे लिए एकमात्र संभावित तरीका कस्टम बाइंडिंग का उपयोग कर रहा है। – hgulyan

1

डिफ़ॉल्ट रूप से, WSHttp बाइंडिंग केवल सुरक्षा सत्रों की अनुमति देता है। यह डब्ल्यूसीएफ की अवधारणा है और परिवहन से जुड़ा हुआ नहीं है। एक सुरक्षा सत्र https पर एक सत्र नहीं है, लेकिन पारस्परिक प्रमाणीकरण वाला सत्र है। यह संदेश सुरक्षा जोड़कर हासिल किया जाता है।

आपकी सेवा के आधार पर, आप इस config

<bindings> 
     <wsHttpBinding> 
     <binding name="wsHttpBindingConfig"> 
      <security mode="TransportWithMessageCredential"> 
      <!-- configure transport & message security here if needed--> 
      </security> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 

clientside पर लागू करना चाहिए, यहाँ एक सरल इकाई परीक्षण

[TestMethod] 
    public void TestSecuritySession() 
    { 
     //remove this is certificate is valid 
     ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback((sender, certificate, chain, sslPolicyErrors) => { return true; }); 

     var binding = new WSHttpBinding(); 
     binding.Security = new WSHttpSecurity() { Mode = SecurityMode.TransportWithMessageCredential}; 
     ChannelFactory<ITestService> Factory = new ChannelFactory<ITestService>(binding, new EndpointAddress("https://localhost/TestService.svc")); 

     Factory.Open(); 
     var channel = Factory.CreateChannel(); 

     //call service here 

     (channel as IClientChannel).Close(); 

     Factory.Close(); 
    } 
+0

क्या मेरा सत्र आपके मामले में काम करेगा, अगर मैं InstanceContextMode PerSession बना देता हूं? – hgulyan

+0

@hgulyan हां बिल्कुल। एक सेवा विधि में सत्र/आवृत्ति विशिष्ट डेटा लौटकर आप आसानी से इस व्यवहार का परीक्षण कर सकते हैं। – Cybermaxs

1

wsHttpBinding WCF सत्र का समर्थन करने के reliableSession की आवश्यकता है, और विश्वसनीय सत्र कस्टम की आवश्यकता होती है एसएसएल का समर्थन करने के लिए बाध्यकारी। तो एसएसएल पर डब्ल्यूसीएफ सत्रों के लिए पूछना और wsHttp बाइंडिंग के साथ प्रश्न के बाहर जैसा लगता है मैं कह सकता हूं।

+1

मुझे लगता है, आप सही हैं, लेकिन मुझे क्या करना चाहिए, अगर मुझे एसएसएल और सत्र दोनों काम करने की ज़रूरत है? – hgulyan