2008-09-11 22 views
13

मैंने एक डब्लूसीएफ सेवा (बेसिक एचटीपी बाइंडिंग) के साथ संचारित एक सिल्वरलाइट 2 एप्लीकेशन लिखा है। सिल्वरलाइट सामग्री की मेजबानी करने वाली साइट एएसपी.NET सदस्यता प्रदाता का उपयोग करके संरक्षित है। मैं अपने डब्ल्यूसीएफ सेवा से HttpContext.Current.User.Identity.Name का उपयोग कर वर्तमान उपयोगकर्ता तक पहुंच सकता हूं, और मैंने AspNetCompatibilityRequirementsMode चालू कर दिया है।डब्ल्यूसीएफ, एएसपी.नेट सदस्यता प्रदाता और प्रमाणीकरण सेवा

अब मैं एक ही वेब सेवा का उपयोग कर एक विंडोज़ एप्लीकेशन लिखना चाहता हूं। प्रमाणीकरण को संभालने के लिए मैंने Authentication service को सक्षम किया है, और मेरे उपयोगकर्ता को प्रमाणित करने के लिए "लॉगिन" पर कॉल कर सकता हूं ... ठीक है, सब अच्छा ... लेकिन मैं अपने अन्य सेवा क्लाइंट पर प्रमाणीकरण कुकी कैसे सेट करूं ?!

दोनों सेवाओं के एक ही डोमेन पर होस्ट किया गया है

  • MyDataService.svc < - एक अपने डेटा के साथ काम कर
  • AuthenticationService.svc < - एक विंडोज़ अनुप्रयोग को प्रमाणित करने के कॉल करने के लिए है।

मैं खिड़कियों ग्राहक के लिए एक नई सेवा बनाने के लिए, या किसी अन्य बंधन का उपयोग नहीं करना चाहते हैं ...

क्लाइंट अनुप्रयोग सेवा एक और विकल्प है, लेकिन सभी उदाहरण कैसे को दिखाने के लिए सीमित है उपयोगकर्ता, भूमिकाएं और उसकी प्रोफ़ाइल प्राप्त करें ... लेकिन क्लाइंट एप्लिकेशन सेवाओं का उपयोग करके प्रमाणीकृत होने के बाद, उसी सर्वर पर वापस कॉल करते समय मेरे सेवा क्लाइंट से प्रमाणीकरण कुकी संलग्न करने का एक तरीका होना चाहिए।

सहयोगियों समाधान एक wsHttpBinding अंत बिंदु जोड़ रहा है से इनपुट के अनुसार, लेकिन मुझे लगता है मैं कुछ मिल सकता है ... इस तरह के WCF द्वारा बनाई गई उन लोगों के रूप

उत्तर

5

मुझे अंत में यह काम करने का एक तरीका मिला। प्रमाणीकरण के लिए मैं "WCF Authentication Service" का उपयोग कर रहा हूं। सेवा प्रमाणित करते समय प्रमाणीकरण कुकी सेट करने का प्रयास किया जाएगा। मुझे इस कुकी को प्रतिक्रिया से बाहर करने की आवश्यकता है, और उसी मशीन पर अन्य वेब सेवाओं के लिए किए गए किसी भी अन्य अनुरोध में इसे जोड़ने की आवश्यकता है। ऐसा करने के लिए कोड इस तरह दिखता है:

var authService = new AuthService.AuthenticationServiceClient(); 
var diveService = new DiveLogService.DiveLogServiceClient(); 

string cookieHeader = ""; 
using (OperationContextScope scope = new OperationContextScope(authService.InnerChannel)) 
{ 
    HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty(); 
    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestProperty; 
    bool isGood = authService.Login("jonas", "jonas", string.Empty, true); 
    MessageProperties properties = OperationContext.Current.IncomingMessageProperties; 
    HttpResponseMessageProperty responseProperty = (HttpResponseMessageProperty)properties[HttpResponseMessageProperty.Name]; 
    cookieHeader = responseProperty.Headers[HttpResponseHeader.SetCookie];     
} 

using (OperationContextScope scope = new OperationContextScope(diveService.InnerChannel)) 
{ 
    HttpRequestMessageProperty httpRequest = new HttpRequestMessageProperty(); 
    OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequest); 
    httpRequest.Headers.Add(HttpRequestHeader.Cookie, cookieHeader); 
    var res = diveService.GetDives(); 
}  

आप मैं दो सेवा ग्राहकों, प्रमाणीकरण सेवा के लिए एक है, और सेवा मैं वास्तव में उपयोग करने के लिए जा रहा हूँ के लिए एक है देख सकते हैं। पहला ब्लॉक लॉग इन विधि को कॉल करेगा, और प्रमाणीकरण कुकी को प्रतिक्रिया से बाहर ले जाएगा। दूसरा ब्लॉक "GetDives" सेवा विधि को कॉल करने से पहले अनुरोध में हेडर जोड़ देगा।

मैं इस कोड से बिल्कुल खुश नहीं हूं, और मुझे लगता है कि "सेवा संदर्भ" के अंत में "वेब संदर्भ" का उपयोग करने के लिए बेहतर विकल्प हो सकता है और इसके बजाय .NET 2.0 स्टैक का उपयोग करना संभव है।

2

वेब सेवाओं, आशा करती हूं कि, अक्सर सबसे अच्छा उपयोग किया जाता है एक "स्टेटलेस" तरीके से, इसलिए एक वेब सेवा के लिए प्रत्येक कॉल फिर से शुरू होता है। यह सर्वर कोड को सरल बनाता है, क्योंकि "सत्र" रखने की कोई आवश्यकता नहीं है जो क्लाइंट की स्थिति को याद करता है। यह क्लाइंट कोड को भी सरल बनाता है क्योंकि सर्वर की स्थिति के बारे में कुछ मानते हुए टिकट, कुकीज़ या अन्य गीगाव रखने की आवश्यकता नहीं होती है।

वर्णित तरीके से दो सेवाओं को बनाना राज्य की स्थिति का परिचय देता है। क्लाइंट या तो "प्रमाणीकृत" या "प्रमाणित नहीं है", और MyDataService.svc को पता लगाना है कि कौन सा है।

जैसा कि होता है, मुझे लगता है कि सदस्यता प्रदाता को प्रत्येक सेवा को कॉल करने के लिए प्रमाणीकृत करने के लिए WCF को अच्छी तरह से काम करने के लिए उपयोग किया जाता है। तो, दिए गए उदाहरण में, आप सदस्यता प्रदाता प्रमाणीकरण gubbins को MyDataService के लिए सेवा कॉन्फ़िगरेशन में जोड़ना चाहते हैं, और बिल्कुल अलग प्रमाणीकरण सेवा नहीं है।

विवरण के लिए, एमएसडीएन आलेख here देखें।

[मेरे बारे में यह बहुत आकर्षक है, क्योंकि मैं आलसी हूं, यह पूरी तरह से घोषणात्मक है। मैं एप्लिकेशन के लिए app.config में अपने सदस्यता प्रदाता के लिए सही कॉन्फ़िगरेशन प्रविष्टियों को स्कैटर करता हूं और! बिंगो! सेवा में प्रत्येक अनुबंध के लिए सभी कॉल प्रमाणित हैं।]

यह ध्यान रखना उचित है कि यह विशेष रूप से तेज़ नहीं होगा। यदि आप अपने प्रमाणीकरण डेटाबेस के लिए SQL सर्वर का उपयोग कर रहे हैं तो आपके पास कम से कम एक, शायद दो संग्रहीत प्रक्रिया कॉल प्रति सेवा कॉल होगी। कई मामलों में (विशेष रूप से HTTP बाइंडिंग के लिए) सेवा कॉल का ओवरहेड स्वयं अधिक होगा; यदि नहीं, तो सदस्यता प्रदाता के अपने कार्यान्वयन को रोल करने पर विचार करें जो प्रमाणन अनुरोधों को कैश करता है।

एक बात यह है कि यह नहीं है "लॉगिन" क्षमता प्रदान करने की क्षमता है। इसके लिए, आप या तो एक (प्रमाणीकृत!) सेवा अनुबंध प्रदान कर सकते हैं जो कुछ भी नहीं करता है (प्रमाणीकरण विफल होने पर गलती उठाने के अलावा), या आप मूल संदर्भित आलेख में वर्णित सदस्यता प्रदाता सेवा का उपयोग कर सकते हैं।

0

कस्टम संदेश निरीक्षक & व्यवहार के पीछे अतिरिक्त कोड को छिपाना संभव है ताकि आपको ऑपरेशन कॉन्टेक्स्टस्कोप के साथ टिंकरिंग की देखभाल करने की आवश्यकता न हो।

मैं बाद में कुछ नकली करने और इसे आपको भेजने की कोशिश करूंगा।

--larsw

+1

महान लार्स लगता है। मुझे एक अच्छा उदाहरण दें ताकि हम "इस चूसने वाले को बंद कर सकें"; चीयर्स, जोनास –

0

आप System.Net में CookieContainer वस्तु पर एक नज़र रखना चाहिए। यह ऑब्जेक्ट गैर-ब्राउज़र क्लाइंट को कुकीज़ पर लटकने की अनुमति देता है। आखिरी बार जब मैंने उस समस्या में भाग लिया तो मेरी टीम ने यही किया।

Here is a brief article इसका उपयोग करने के तरीके पर कैसे जाएं। वहाँ बेहतर हो सकता है, लेकिन यह आपको शुरू करना चाहिए।

हम डब्ल्यूसीएफ सेवाओं और सिल्वरलाइट 2 आवेदन के हमारे वर्तमान सेट के लिए स्टेटलेस मार्ग गए। SilverWithMessageCredential सुरक्षा से बंधे सेवाओं के साथ काम करने के लिए सिल्वरलाइट 2 प्राप्त करना संभव है, हालांकि यह सिल्वरलाइट पक्ष पर कुछ कस्टम सुरक्षा कोड लेता है। उपरोक्त यह है कि कोई भी संदेश संदेश शीर्षकों में उपयोगकर्ता नाम और पासवर्ड सेट करके सेवाओं तक पहुंच सकता है। यह एक बार कस्टम IRequestChannel कार्यान्वयन में किया जा सकता है ताकि डेवलपर्स को मूल्यों को स्वयं सेट करने के बारे में चिंता करने की आवश्यकता न हो। हालांकि डब्ल्यूसीएफ के पास ऐसा करने के लिए डेवलपर्स के लिए एक आसान तरीका है, जो मुझे विश्वास है कि सेवा है। सुरक्षा। उपयोगकर्ता नाम और सेवाप्रॉक्सी। सुरक्षा। पासवर्ड या कुछ समान रूप से सरल है।

0

मैंने कुछ समय पहले लिखा था जब मैं क्लाइंट एप्लिकेशन सेवाओं का उपयोग वेब सेवाओं के खिलाफ प्रमाणित करने के लिए कर रहा था। यह कुकी हेडर डालने के लिए एक संदेश निरीक्षक का उपयोग करता है। दस्तावेज़ीकरण और एक डेमो परियोजना के साथ एक शब्द फ़ाइल है। यद्यपि यह ठीक नहीं है कि आप क्या कर रहे हैं, यह बहुत करीब है। आप इसे here से डाउनलोड कर सकते हैं।

1

ग्राहक पर (system.serviceModel > < अंदर) शामिल करने के लिए सेवा के लिए अपने < बाध्यकारी > टैग संशोधित: AllowCookies = "true"

एप्लिकेशन अब कुकी जारी रहती है और इसका इस्तेमाल करना चाहिए। आप ध्यान दें कि लॉग इन करने के बाद IsLoggedIn अब सत्य लौटाता है - यदि आप कुकीज की अनुमति नहीं दे रहे हैं तो यह झूठा रिटर्न देता है।

संबंधित मुद्दे