PDA

View Full Version : WebService ,Session & Authentication



MH2538
یک شنبه 24 تیر 1386, 11:10 صبح
من یک برنامه سه لایه با استفاده از وب سرویس نوشتم روی پایگاه داده ای اوراکل نوشتم.
وب سرویس من (لایه میانی برنامه) مجموعه ای از توابع مختلف رو در اختیار لایه کاربردی قرار می دهد.
همه چیز هم درست کار می کند . اما مشکلی که من دارم تو این است که هر کسی که آدرس سرور و
پورت اون رو بدونه می تونه از توابع استفاده کنه.
حالا چطوری با نام کاربری و رمز عبور از توابع خودم محافظت کنم.
Session هم که در وب سرویس تنها درد سطح تابع پشتیبانی می شود یعنی وقتی یک تابع آغاز می شود Session سا خته می شه و در انتهای تابع هم از بین می ره
بنابراین از روش های معمول تحت وب نمی وتونم از این روش استفاده کنم.
در یافت نام کاربری و رمز عبور در هر تابع هم که اصلاً منطقی نیست .
به نظر شما چکار باید بکنم تا توایع من بدون وارد کردن نام کاربری و رمز عبور در دسترس نباشه و در عین حال هر برنامه در هر بار که اجرا می شه تنها یکبار نیاز به login داشته باشه.؟!!

reza_rad
یک شنبه 24 تیر 1386, 11:48 صبح
یک راه می تونه این باشه:
شما در وب سرویس خودت متدهایی داری که کارهات رو انجام میدن و ...
حالا یک متد همونجا داشته باشی که یوزر رو authenticate کنه. اگه درست بود اجازه استفاده از بقیه متدها رو بهت بده. از اونجایی که وقتی تو داری این وب سرویس رو توی برنامه ات استفاده می کنی مثل یه آبجکت باهاش کار می کنی قابل انجام هست چون این آبجکت خودش توسط اون وب متد یکبار چک می کنه که آیا یوزری که داره کاری می کنه Authenticate شده یا خیر.

mehdi.mousavi
یک شنبه 24 تیر 1386, 21:10 عصر
من یک برنامه سه لایه با استفاده از وب سرویس نوشتم روی پایگاه داده ای اوراکل نوشتم.
وب سرویس من (لایه میانی برنامه) مجموعه ای از توابع مختلف رو در اختیار لایه کاربردی قرار می دهد.
همه چیز هم درست کار می کند . اما مشکلی که من دارم تو این است که هر کسی که آدرس سرور و
پورت اون رو بدونه می تونه از توابع استفاده کنه.
حالا چطوری با نام کاربری و رمز عبور از توابع خودم محافظت کنم.
Session هم که در وب سرویس تنها درد سطح تابع پشتیبانی می شود یعنی وقتی یک تابع آغاز می شود Session سا خته می شه و در انتهای تابع هم از بین می ره
بنابراین از روش های معمول تحت وب نمی وتونم از این روش استفاده کنم.
در یافت نام کاربری و رمز عبور در هر تابع هم که اصلاً منطقی نیست .
به نظر شما چکار باید بکنم تا توایع من بدون وارد کردن نام کاربری و رمز عبور در دسترس نباشه و در عین حال هر برنامه در هر بار که اجرا می شه تنها یکبار نیاز به login داشته باشه.؟!!


سلام.
شما در چند لایه میتونید از Web Service اتون محافطت کنید:

1. IIS - یعنی باید برید و روی فولدری که WS رو در اون ریختید، ID/PWD بذارید. به این ترتیب تا کسی ID/PWD رو نزنه نمیتونه به فایل WSDL و در نتیجه وب سرویس شما دسترسی داشته باشه. اگر اینکارو کنید میتونید از یکی از روشهای Basic، Digest یا Windows Integration استفاده کنید.

2. میتونید Credential ها رو در غالب SOAP Header با هر متود بصورت inbound به وب سرویس ارسال کنید. سمت وب سرویس، Credential ها رو چک می کنید و اگه همه چی OK بود، اجازه میدید متود روند طبیعیشو ادامه بده. این تمیزترین کاری هستش که میشه انجام داد اما باید تو این زمینه تجربه داشته باشید، و الا ممکنه نتیجه کار اونقدر که فکر میکنید Secure از آب در نیاد.

3. با استفاده از Session ها که گفتید نمیشه، هم میتونید این کارو کنید.
باید سمت Client حتما یه Cookie ایجاد کنید و متود هاتون رو SessionEnabled کنید تا بتونید از این روش استفاده کنید.

در صورت استفاده از روش 2 یا 3 باید حتما برای Packet های ارسالیتون به وب سرویس یه TTL در نظر بگیرید. منظورم Time To Live هستش تا به این ترتیب جلوی حملات Session Hijacking رو بگیرید. یعنی اگر کسی بسته های ارسال شده از یه Client معتبر به وب سرویس رو ذخیره کرد و مثلا یک ساعت بعد همونا رو به سمت وب سرویس ارسال کرد، شما باید سمت وب سرویس بتونید تشخیص بدین که بسته منقضی شده و Web method call رو reject کنید.

4. میتونید از Microsoft Passport استفاده کنید.

5. میتونید از X.509 Certification ها استفاده کنید.

در واقع ببینید، دو مساله اینجا مورد توجه هستش. یکی اینکه ID/PWD شما در برابر Man in the middle attack محافطت بشه (هنگام Authenticate شدن) و دوم اینکه اطلاعات رد و بدل شمده بین Client و وب سرویس Encrypt بشه. اگر دقیقا بگید کدوم از این دو مد نظرتون، بهتون دقیقتر جواب میدم.

reza_rad
دوشنبه 25 تیر 1386, 07:29 صبح
Web Service Authentication (http://www.codeproject.com/cs/webservices/WebServiceAuthentication.asp)

Authentication for Web Services (using SOAP headers) (http://www.codeproject.com/cs/webservices/authforwebservices.asp)


An introduction to Web Service Security using WSE - Part I (http://www.codeproject.com/webservices/WS-Security.asp)


.

مهدی کرامتی
دوشنبه 25 تیر 1386, 08:32 صبح
این WSE صحبت های خوبی میکنه، اما در عمل استفاده از اون هم پیچیده است، و هم نیاز به نصب شدن یک سری اسمبلی ها روی سرور داره که هر هاستی نصب اونها رو قبول نمیکنه.

MH2538
دوشنبه 25 تیر 1386, 10:51 صبح
سلام
ممنون از راهنماییتون ولی مشکل توی ارسال اطلاعات به روشی که trasnparency «داشته باشه نیست مشکل من اینه :
فرض کنید دفعه اول که کاربر می خواد یه تابع رو اجرا کنه من با یک تابع سمت وب سرویس و دریافت نام کاربر و رمز عبور ، کاربر رو اعتبارسنجی کنم و بعد تابع مورد نظر کاربر رو اجرا کنم.
مشکل اینجاست که بعد از پایان تابع نتایج این اعتبار سنجی از بین می ره .
تو وب من این نتایج رو تو session نگه می داشتم ولی اینجا عمر session حداکثر در سطح تابع است.
از جانب دیگه ، من این برنامه رو دارم برای embedded OS می نویسم بنابراین بدلایل خاصی دسترسی به کوکی هم ندارم.

ضمن اینکه پیچیدگی های نصب و داشتن امکان نصب هم همونطور که DelphiAssistant گفت خودش از مسایلی که وجود داره

با تشکر

mehdi.mousavi
دوشنبه 25 تیر 1386, 23:06 عصر
سلام
ممنون از راهنماییتون ولی مشکل توی ارسال اطلاعات به روشی که trasnparency «داشته باشه نیست مشکل من اینه :
فرض کنید دفعه اول که کاربر می خواد یه تابع رو اجرا کنه من با یک تابع سمت وب سرویس و دریافت نام کاربر و رمز عبور ، کاربر رو اعتبارسنجی کنم و بعد تابع مورد نظر کاربر رو اجرا کنم.
مشکل اینجاست که بعد از پایان تابع نتایج این اعتبار سنجی از بین می ره .
تو وب من این نتایج رو تو session نگه می داشتم ولی اینجا عمر session حداکثر در سطح تابع است.
از جانب دیگه ، من این برنامه رو دارم برای embedded OS می نویسم بنابراین بدلایل خاصی دسترسی به کوکی هم ندارم.

ضمن اینکه پیچیدگی های نصب و داشتن امکان نصب هم همونطور که DelphiAssistant گفت خودش از مسایلی که وجود داره

با تشکر

سلام.
این حرفتون درست نیست که "عمر Session حداکثر در سطح یک تابع است". اگر یه خورده به این حرف فکر کنید، می بینید که اگه Session ها lifetime اشون در سطح تابع باشه، اونوقت با یه local variable فرقی نمی کنن! پس اینطور نیست!

برای اینکه یک یا چند تابع در وب سرویس رو بتونید در یک Session بکار ببرید، باید وب متودهای مورد نظرتون رو با Attribute ای به اسم EnableSession، دکوریت کنید. مثلا:


[ WebMethod(EnableSession=true) ]
public void DoWhatever()

به این ترتیب به ASP.NET دارید یه hint میدید که بدونه متود DoWhateverُ در یک وضعیت Session-full قراره استفاده بشه. کلیه متودهای دیگه مورد نظرتون رو هم که قراره به Session دسترسی داشته باشن، باید با همین روش decorate کنید. اما این فقط بخشی از کاره.

بخش دیگه سمت Client باید انجام بشه. به این ترتیب که باید به Proxy ی تولید شده توسط VS، یک instance از کلاس CookieContainer بدید:



System.Net.CookieContainer cc = new System.Net.CookieContainer();
proxyInstance.CookieContainer = cc;

ممکنه همه این کار ها رو انجام بدید و متوجه بشید که هنوز Session ها در دسترس نیستن (سمت سرور!). اشتباهی که معمولا افراد می کنن این هستش که instance های متفاوت از Proxy اولید می کنن و انتطار دارن که Session تولید شده در یک وب متود، در وب متود دیگه ای در دسترس باشه. بله، البته که اینطور نیست!

شما باید مطمئن بشید که در طول اجرای برنامه فقط یک instance از کلاس Proxy تولید می کنید و ... در غیر اینصورت باید کارهای دیگه ای انجام بدید که از حوصله این بحث خارجه. یادتون باشه که CookieContainer همونطور که از اسمش پیداست، محلی برای ذخیره Cookie هاست و در این مورد، حاوی اطلاعات Session ای هستش که شما سمت سرور تولید می کنید. این اطلاعات در این bag ذخیره میشن و با رفت و آمدهای بعدی، به سرور ارسال میشن و همه چی اونطوری که به نظر می رسه کار میکنه....

اما یه نکته. یکی از خوبیهای وب سرویس ها، اینه که state-less هستن. شما با این کار دارید وب سرویس رو به وضعیت state-full می برید و باید خیلی مراقب باشید که چیکار می کنید. State-full کردن یک وب سرویس به صرف رد و بدل کردن ID/PWD مطلقا کار درستی نیست و من اینو به هیچکس توصیه نمیکنم، اگر چه روش کار رو توضیح دادم.

MH2538
سه شنبه 26 تیر 1386, 06:06 صبح
دوست عزیزم mehdi6775
من قبل از مطرح کردن این سئوال کارهایی که شما در اینجا اشاره کردید رو انجام دادم. از جمله EnableSession
در مورد instance هم ، باید بگم دیگه تقریباً همه می دونن که نمونه های مختلف از یک شی ، با هم یکی نیستند و ....
در مورد کوکی هم که من در پست قبل توضیح دادم نمی تونم ازش استفاده کنم ، که اون هم دلایل خودش رو داره.

mehdi.mousavi
سه شنبه 26 تیر 1386, 20:17 عصر
دوست عزیزم mehdi6775
من قبل از مطرح کردن این سئوال کارهایی که شما در اینجا اشاره کردید رو انجام دادم. از جمله EnableSession
در مورد instance هم ، باید بگم دیگه تقریباً همه می دونن که نمونه های مختلف از یک شی ، با هم یکی نیستند و ....
در مورد کوکی هم که من در پست قبل توضیح دادم نمی تونم ازش استفاده کنم ، که اون هم دلایل خودش رو داره.

سلام.
ما به این جور شرایط میگیم Mutually Exclusive، یعنی اینکه دو چیزی رو که هرگز در کنار هم نمیتونن حاضر بشن رو بخواهیم به نحوی در کنار هم قرار بدیم. مثلا بگیم: "من میخوام از ISAPI ها استفاده کنم، اما نمیخوام رو ماشینم IIS نصب کنم." یا فرضا بگیم "من میخوام وب سرویسم state-full باشه، اما نمیتونم از Cookie ها استفاده کنم." و در عین حال اصرار به انجام اون کار غیر ممکن داشته باشیم.

در مورد instance ها... قصد توهین و جسارت نداشتم، خواستم مطمئن بشم که نکته ای رو از قلم ننداختم. نوشتن جمله هایی مثل "Session هم که در وب سرویس تنها در سطح تابع پشتیبانی می شود" واقعا خطرناکه و براحتی میتونه خیلی از افراد رو گمراه کنه. شما پیش فرضی در ذهنتون داشتید (عدم استفاده از CookieContainer) و عنوان نکردینش و چنین جمله ای رو نوشتید! نه من، و نه هیچکس دیگه ای که سوال شما رو میخونه، نمیتونه متوجه بشه که شما چه پیش فرضی در ذهنتون داشتید؛ چون اون رو به رشته تحریر در نیاوردین.

در هر حال، اگر هنوز اصرار دارید که از Session ها استفاده کنید، اما بهش محلی برای ذخیره اطلاعات Session ندید، باید منتظر معجزه باشید.

dotnetdeveloper
یک شنبه 13 اردیبهشت 1388, 11:58 صبح
با سلام
من در سمت Client از C++ استفاده می کنم.
چطوری می تونم مثل C# (کد زیر) عمل ست کردن CookieContainer رو در C++ و MFC انجام بدم؟
حدس می زنم که باید در فایل wsdl تغییراتی ایجاد کنم ولی چیزی پیدا نکردم.
لطفا در صورت امکان راهنمایی کنید.
با تشکر.

System.Net.CookieContainer cc = new System.Net.CookieContainer();
proxyInstance.CookieContainer = cc;

mehdi.mousavi
یک شنبه 13 اردیبهشت 1388, 12:36 عصر
با سلام
من در سمت Client از C++ استفاده می کنم.
چطوری می تونم مثل C# (کد زیر) عمل ست کردن CookieContainer رو در C++ و MFC انجام بدم؟
حدس می زنم که باید در فایل wsdl تغییراتی ایجاد کنم ولی چیزی پیدا نکردم. لطفا در صورت امکان راهنمایی کنید. با تشکر.

System.Net.CookieContainer cc = new System.Net.CookieContainer();
proxyInstance.CookieContainer = cc;

سلام.
خیر، نیازی به تغییر در WSDL نیست. در MFC، شما می تونید از کلاس CInternetSession به این منظور استفاده کنید. این کلاس وظیفه مدیریت Cookie Database شما رو بعهده داره. برای آشنایی با نحوه کار این کلاس، لطفا به MSDN رجوع کنید.

MH2538
یک شنبه 13 اردیبهشت 1388, 13:41 عصر
سلام.
ما به این جور شرایط میگیم Mutually Exclusive، یعنی اینکه دو چیزی رو که هرگز در کنار هم نمیتونن حاضر بشن رو بخواهیم به نحوی در کنار هم قرار بدیم. مثلا بگیم: "من میخوام از ISAPI ها استفاده کنم، اما نمیخوام رو ماشینم IIS نصب کنم." یا فرضا بگیم "من میخوام وب سرویسم state-full باشه، اما نمیتونم از Cookie ها استفاده کنم." و در عین حال اصرار به انجام اون کار غیر ممکن داشته باشیم.

در مورد instance ها... قصد توهین و جسارت نداشتم، خواستم مطمئن بشم که نکته ای رو از قلم ننداختم. نوشتن جمله هایی مثل "Session هم که در وب سرویس تنها در سطح تابع پشتیبانی می شود" واقعا خطرناکه و براحتی میتونه خیلی از افراد رو گمراه کنه. شما پیش فرضی در ذهنتون داشتید (عدم استفاده از CookieContainer) و عنوان نکردینش و چنین جمله ای رو نوشتید! نه من، و نه هیچکس دیگه ای که سوال شما رو میخونه، نمیتونه متوجه بشه که شما چه پیش فرضی در ذهنتون داشتید؛ چون اون رو به رشته تحریر در نیاوردین.

در هر حال، اگر هنوز اصرار دارید که از Session ها استفاده کنید، اما بهش محلی برای ذخیره اطلاعات Session ندید، باید منتظر معجزه باشید.

دوست عزیزم سلام
من مجدد می نویسم که قصد دارم از وب سرویس در یک Embeded OS Device استفاده کنم. ساده اش میشه تجهیزاتی که از سیستم عامل هایی مثل ویندوز CE و یا ویندوز Mobile استفاده می کنند.
در ویندوز CE و Mobile و با زبان #C استفاده از CookieContainer ممکن نیست.(ساده اش میشه پشتیبانی نمیشه)
اما من منتظر معجزه نموندم و بالاخره مشکل رو با کمی تغییر حل کردم .

mehdi.mousavi
یک شنبه 13 اردیبهشت 1388, 14:19 عصر
دوست عزیزم سلام من مجدد می نویسم که قصد دارم از وب سرویس در یک Embeded OS Device استفاده کنم. ساده اش میشه تجهیزاتی که از سیستم عامل هایی مثل ویندوز CE و یا ویندوز Mobile استفاده می کنند. در ویندوز CE و Mobile و با زبان #C استفاده از CookieContainer ممکن نیست.(ساده اش میشه پشتیبانی نمیشه) اما من منتظر معجزه نموندم و بالاخره مشکل رو با کمی تغییر حل کردم .

سلام.
پاسخ من مال 26 تیر 1386 هستش، یعنی تقریبا دو سال پیش! چی شده امروز دوباره یاد این مساله افتادید؟ من الان پاسخ سوال dotnetdeveloper رو دادم، که دنبال معادلی برای CookieContainer در MFC بود... در واقع ایشون باید جای دیگه ای این سوال رو مطرح می کرد، نه در این Thread. (ساده اش میشه، شما چرا بخودت گرفتی؟)

اما در مورد سوال شما، من بازهم Thread رو از اول مرور کردم. اگر بفرمایید چه تغییری دادید که مشکل حل شد، خوشحال میشم. (ساده اش میشه چطوری معجزه رخ داد؟)

در هر حال، اگر از همون روز اول (2 سال پیش) می گفتید که Cookie Collection ها روی .NET /CF پشتیبانی نمیشن، بجای اینکه بنویسید "من این برنامه رو دارم برای embedded OS می نویسم بنابراین بدلایل خاصی دسترسی به کوکی هم ندارم"، همون 2 سال پیش می گفتم چیکار باید کنید.

از اونجاییکه Cookie Collection ها روی .NET cf پشتیبانی نمیشن، یک راه برای استفاده Stateful از وب سرویسها، به دام انداختن دریافت و ارسال پاسخها هستش، به این ترتیب این فرصت رو دارید تا اطلاعات مورد نظر رو در Header بطور دستی قرار بدید...

majidmjh
یک شنبه 23 مرداد 1390, 19:12 عصر
پاسخی که آقای موسوی دادن و گفتن که پاسخ قبلیشون مال 2 سال پیشه الان 2 سال ازش می گذره !!! و از پاسخ اولی 4 سال !

یه راه راحت تر هم هست که می گه :


Context.Session("Counter")


البته


<WebMethod(EnableSession:=True)> _


فراموش نشه !