कैच -22 WIF द्वारा सुरक्षित टीसीपी WCF सेवा को रोकता है; मेरे क्रिसमस को बर्बाद करना, मानसिक स्वास्थ्य


181

मुझे WIF का उपयोग करके एक स्ट्रीम WCF net.tcp सर्विस एंडपॉइंट को सुरक्षित करने की आवश्यकता है । यह हमारे टोकन सर्वर के खिलाफ आने वाली कॉल को प्रमाणित करना चाहिए। सेवा को स्ट्रीम किया गया है क्योंकि यह बड़ी मात्रा में डेटा एन सामान को स्थानांतरित करने के लिए डिज़ाइन किया गया है।

यह असंभव प्रतीत होता है। और अगर मैं पकड़ में नहीं आ सका, तो मेरा क्रिसमस बर्बाद हो जाएगा और मैं अपने आप को एक गटर में मरने के लिए पी लूंगा, जबकि मेरी दुकानदार धीरे-धीरे ठंडा होने वाले शरीर पर कदम रखेंगे। टोट्स गंभीर, आप लोग।

यह असंभव क्यों है? यहां कैच -22 है।

क्लाइंट पर, मुझे हमारे टोकन सर्वर से मिलने वाले GenericXmlSecurityToken के साथ एक चैनल बनाने की आवश्यकता है । कोई बात नहीं।

// people around here hate the Framework Design Guidelines.
var token = Authentication.Current._Token;
var service = base.ChannelFactory.CreateChannelWithIssuedToken(token);
return service.Derp();

क्या मैंने कहा "कोई समस्या नहीं"? Problemo। वास्तव में, NullReferenceExceptionशैली समस्या।

"भाई," मैंने फ्रेमवर्क से पूछा, "क्या आप भी चेक करते हैं?" फ्रेमवर्क चुप था, इसलिए मैं असंतुष्ट था और उसने पाया

((IChannel)(object)tChannel).
    GetProperty<ChannelParameterCollection>().
    Add(federatedClientCredentialsParameter);

अपवाद का स्रोत था, और यह कि GetPropertyकॉल वापस आ रहा था null। तो, डब्ल्यूटीएफ? यह बताता है कि यदि मैं संदेश सुरक्षा को चालू करता हूं और क्लाइंट क्रेडेंशियल प्रकार सेट करता हूं, IssuedTokenतो यह संपत्ति अब ClientFactory(प्रॉपिप: आईसीहनेल, बस्टर्ड में बराबर "सेटप्रॉपर्टी) में मौजूद है।

<binding name="OMGWTFLOL22" transferMode="Streamed" >
    <security mode="Message">
        <message clientCredentialType="IssuedToken"/>
    </security>
</binding>

मिठाई। अब और नहीं। हालांकि, अब मेरे मुवक्किल को जन्म के समय दोष है (फिर भी उसे प्यार करो, थियो)। WCF डायग्नोस्टिक्स (प्रोटिप) के माध्यम से खुदाई करना: अपने सबसे बुरे दुश्मनों को ऐसा करने के बाद उन्हें कुचलने और उन्हें आपके सामने चलाने से पहले करें, लेकिन अपनी महिलाओं और बच्चों के विलाप का आनंद लेने से ठीक पहले), मैं इसे सर्वर और क्लाइंट के बीच एक सुरक्षा बेमेल के कारण देखता हूं।

अनुरोधित अपग्रेड 'net.tcp: // localhost: 49627 / MyService' द्वारा समर्थित नहीं है। यह बेमेल बाइंडिंग के कारण हो सकता है (उदाहरण के लिए ग्राहक पर सक्षम सुरक्षा और सर्वर पर नहीं)।

मेजबान के आरेखों की जांच करना (फिर से: क्रश, ड्राइव, लॉग पढ़ें, विलाप का आनंद लें), मुझे लगता है कि यह सच है

प्रोटोकॉल प्रकार अनुप्रयोग / ssl-tls एक ऐसी सेवा को भेजा गया था जो उस प्रकार के उन्नयन का समर्थन नहीं करती है।

"ठीक है, आत्म," मैं कहता हूं, "मैं मेजबान पर संदेश सुरक्षा को चालू करूंगा!" और मैं करता हूँ। यदि आप जानना चाहते हैं कि यह कैसा दिखता है, तो यह क्लाइंट कॉन्फिगर की एक सटीक प्रति है। देखो।

परिणाम: कबूम।

बाइंडिंग ('NetTcpBinding', ' http://tempuri.org/ ') स्ट्रीमिंग का समर्थन करता है जिसे संदेश स्तर की सुरक्षा के साथ एक साथ कॉन्फ़िगर नहीं किया जा सकता है। एक भिन्न स्थानांतरण मोड चुनने या परिवहन स्तर सुरक्षा चुनने पर विचार करें।

इसलिए, मेरे मेजबान को टोकन के माध्यम से प्रवाहित और सुरक्षित नहीं किया जा सकता है । 22 कैच।

tl; dr: मैं WIF का उपयोग करके एक स्ट्रीम net.tcp WCF समापन बिंदु कैसे सुरक्षित कर सकता हूं ???


3
ठीक है, शायद अज्ञानी यहाँ सवाल है, लेकिन WIF वास्तव में संदेश मोड की आवश्यकता है? ट्रांसपोर्ट मोड ऐसा लगता है कि यह स्ट्रीमिंग के साथ बेहतर काम करेगा, स्पष्ट रूप से अप्रयुक्त जैसा कुछ<security mode="Transport" /> <transport clientCredentialType="IssuedToken" /> </security>
जोकिम इस्कसन

3
TransportWithMessageCredentialमोड एक और विकल्प हो सकता है।
जोआचिम इस्कसन

3
TMLK, MessageSecurity बफ़र किए गए पेलोड पर हस्ताक्षर कर सकता है और एन्क्रिप्ट कर सकता है, लेकिन धाराओं के साथ काम करते समय फ़ंबल। क्या आपने प्रमाणीकरण का उपयोग करने पर विचार किया हैमोड = НTokenOverTransport?
ओनोसेन्डाई

7
मुझे देखने दो अगर मैं अपनी छुट्टियों को बचाने में मदद करने के लिए अतीत से कुछ भूतों को बुला सकता हूं। यहाँ कुछ संकेत: social.msdn.microsoft.com/Forums/vstudio/en-US/…
OnoSendai

2
कोई भी मौका आप एक टेस्ट-केस प्रोजेक्ट पोस्ट कर सकते हैं जिसे अन्य प्रयोग कर सकते हैं?
एंटिडुह

जवाबों:


41

WCF को स्ट्रीमिंग के साथ कुछ क्षेत्रों में गोचैल्स मिले हैं (मैं आपको, MTOM 1 को देख रहा हूं ) एक मौलिक मुद्दे के कारण कि यह कैसे उपदेशात्मक प्रदर्शन करने में विफल रहता है जिस तरह से ज्यादातर लोग सोचते हैं कि काम करना चाहिए (यह केवल उस चैनल के बाद के अनुरोधों को प्रभावित करता है। , पहला अनुरोध नहीं) ठीक है, इसलिए यह वास्तव में आपका मुद्दा नहीं है, लेकिन कृपया अनुसरण करें क्योंकि मैं अंत में आपके पास पहुंचूंगा। आम तौर पर HTTP चुनौती इस तरह काम करती है:

  1. क्लाइंट सर्वर को गुमनाम रूप से हिट करता है
  2. सर्वर कहता है, क्षमा करें, 401, मुझे प्रमाणीकरण की आवश्यकता है
  3. क्लाइंट प्रमाणीकरण टोकन के साथ सर्वर को हिट करता है
  4. सर्वर स्वीकार करता है।

अब, यदि आप कभी भी सर्वर पर WCF समापन बिंदु पर MTOM स्ट्रीमिंग को सक्षम करने का प्रयास करते हैं, तो यह शिकायत नहीं करेगा। लेकिन, जब आप इसे क्लाइंट प्रॉक्सी पर कॉन्फ़िगर करते हैं (जैसा कि आपको करना चाहिए, तो उन्हें बाइंडिंग से मेल खाना चाहिए) यह एक उग्र मौत में विस्फोट होगा। इसका कारण यह है कि डब्ल्यूसीएफ को रोकने की कोशिश करने वाली घटनाओं का उपरोक्त क्रम यह है:

  1. क्लाइंट एक ही POST में गुमनाम रूप से सर्वर पर 100MB फ़ाइल स्ट्रीम करता है
  2. सर्वर कहते हैं, क्षमा करें, 401, मुझे प्रमाणीकरण की आवश्यकता है
  3. क्लाइंट फिर से एक प्रमाणीकरण हेडर के साथ सर्वर पर 100MB फ़ाइल स्ट्रीम करता है
  4. सर्वर स्वीकार करता है।

ध्यान दें कि आपने केवल 200MB सर्वर को भेजा था जब आपको केवल 100MB भेजने की आवश्यकता थी। खैर, यह समस्या है। उत्तर पहले प्रयास पर प्रमाणीकरण भेजने के लिए है, लेकिन कस्टम व्यवहार लिखे बिना डब्ल्यूसीएफ में यह संभव नहीं है। वैसे भी, मैं पचाता हूं।

तुम्हारी समस्या

सबसे पहले, मैं आपको बताता हूं कि आप जो कोशिश कर रहे हैं वह असंभव २ है । अब, आप अपने पहियों को घूमना बंद करने के लिए, मुझे यह बताने दें:

यह मुझ पर प्रहार करता है कि अब आप समस्या के समान वर्ग में भटक रहे हैं। यदि आप संदेश स्तर की सुरक्षा सक्षम करते हैं, तो ग्राहक को डेटा की पूरी स्ट्रीम को मेमोरी में लोड करना होगा, क्योंकि यह वास्तव में ws-security द्वारा आवश्यक सामान्य हैश फ़ंक्शन और xml हस्ताक्षर के साथ संदेश को बंद कर सकता है। यदि इसे एकल संदेश पर हस्ताक्षर करने के लिए पूरी धारा को पढ़ना है (जो वास्तव में संदेश नहीं है, लेकिन यह एक सतत धारा है) तो आप यहां समस्या देख सकते हैं। WCF को संदेश सुरक्षा की गणना करने के लिए "स्थानीय" एक बार इसे स्ट्रीम करना होगा, फिर इसे सर्वर पर भेजने के लिए फिर से स्ट्रीम करना होगा। यह स्पष्ट रूप से एक मूर्खतापूर्ण बात है, इसलिए WCF डेटा स्ट्रीमिंग के लिए संदेश स्तर सुरक्षा की अनुमति नहीं देता है।

तो, इसका सरल उत्तर यह है कि आपको आरंभिक वेब सेवा के लिए एक पैरामीटर के रूप में या तो SOAP हैडर के रूप में टोकन भेजना चाहिए और इसे मान्य करने के लिए कस्टम व्यवहार का उपयोग करना चाहिए। ऐसा करने के लिए आप WS-Security का उपयोग नहीं कर सकते। सच कहूँ तो, यह सिर्फ एक WCF मुद्दा नहीं है - मैं यह नहीं देख सकता कि यह किसी अन्य स्टैक के लिए व्यावहारिक रूप से कैसे काम कर सकता है।

एमटीओएम समस्या का समाधान

यह सिर्फ एक उदाहरण के लिए है कि कैसे मैंने मूल प्रमाणीकरण के लिए अपने एमटीओएम स्ट्रीमिंग मुद्दे को हल किया, इसलिए शायद आप इसका लाभ उठा सकें और अपने मुद्दे के लिए कुछ समान लागू कर सकें। इसका दोष यह है कि आपके कस्टम संदेश निरीक्षक को सक्षम करने के लिए, आपको ग्राहक प्रॉक्सी (यह सर्वर पर सक्षम रहता है), परिवहन स्तर (SSL) के अलावा सभी सुरक्षा को अक्षम करना होगा:

this._contentService.Endpoint.Behaviors.Add(
    new BasicAuthenticationBehavior(
        username: this.Settings.HttpUser,
        password: this.Settings.HttpPass));
var binding = (BasicHttpBinding)this._contentService.Endpoint.Binding;
binding.Security.Mode = BasicHttpSecurityMode.Transport; // SSL only            
binding.Security.Transport.ClientCredentialType = 
   HttpClientCredentialType.None; // Do not provide

ध्यान दें कि मैंने यहां परिवहन सुरक्षा को बंद कर दिया है क्योंकि मैं खुद को संदेश निरीक्षक और कस्टम व्यवहार का उपयोग करके प्रदान करूंगा:

internal class BasicAuthenticationBehavior : IEndpointBehavior
{
    private readonly string _username;
    private readonly string _password;

    public BasicAuthenticationBehavior(string username, string password)
    {
        this._username = username;
        this._password = password;
    }
    public void AddBindingParameters(ServiceEndpoint endpoint, 
        BindingParameterCollection bindingParameters) { }
    public void ApplyClientBehavior(ServiceEndpoint endpoint,
        ClientRuntime clientRuntime)
    {
        var inspector = new BasicAuthenticationInspector(
            this._username, this._password);
        clientRuntime.MessageInspectors.Add(inspector);
    }
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
        EndpointDispatcher endpointDispatcher) { }
    public void Validate(ServiceEndpoint endpoint) { }
}

internal class BasicAuthenticationInspector : IClientMessageInspector
{
    private readonly string _username;
    private readonly string _password;

    public BasicAuthenticationInspector(string username, string password)
    {
        this._username = username;
        this._password = password;
    }

    public void AfterReceiveReply(ref Message reply,
        object correlationState) { }

    public object BeforeSendRequest(ref Message request,
        IClientChannel channel)
    {
        // we add the headers manually rather than using credentials 
        // due to proxying issues, and with the 101-continue http verb 
        var authInfo = Convert.ToBase64String(
            Encoding.Default.GetBytes(this._username + ":" + this._password));

        var messageProperty = new HttpRequestMessageProperty();
        messageProperty.Headers.Add("Authorization", "Basic " + authInfo);
        request.Properties[HttpRequestMessageProperty.Name] = messageProperty;

        return null;
    }
}

तो, यह उदाहरण किसी के लिए भी है जो एमटीओएम मुद्दे से पीड़ित है, लेकिन यह भी आपके लिए एक कंकाल के रूप में प्राथमिक WIF- सुरक्षित टोकन सेवा द्वारा उत्पन्न अपने टोकन को प्रमाणित करने के लिए कुछ समान लागू करने के लिए है।

उम्मीद है की यह मदद करेगा।

(1) बड़े डेटा और स्ट्रीमिंग

(2) WCF में संदेश सुरक्षा (देखें "नुकसान")


MTOM and Basic Authorization, और MTOM और OAuth2 ?
किवनीत
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.