SSO یک روش احراز هویت است که به کاربران امکان میدهد با استفاده از تنها یک مجموعه دادههای احراز هویت، به روشی امن در چند اپلیکیشن و وبسایت وارد شوند. در این نوشته بررسی میکنیم SSO چیست ، چه مزیتهایی دارد و روش پیادهسازی آن چگونه است.
طرز کار SSO چیست ؟
SSO بر مبنای یک رابطه اعتماد عمل میکند که بین اپلیکیشن که ارائهدهنده سرویس نامیده میشود و یک ارائهدهنده هویت مانند گوگل برقرار شده است. این رابطه اعتماد غالباً بر اساس یک گواهینامه است که بین ارائهدهنده هویت و ارائهدهنده سرویس مبادله میشود. این گواهینامه برای امضا کردن اطلاعات هویت از سمت ارائهدهنده هویت به ارائهدهنده سرویس عرضه میشود تا ارائهدهنده سرویس مطمئن شود کاربر که از منبع شناختهشدهای میآید. در SSO این دادههای هویت به شکل توکن هستند که بخشهای اطلاعاتی برای شناسایی کاربر از قبیل نشانی ایمیل یا نام کاربری را شامل میشوند.
فرایند لاگین به طور معمول شامل مراحل زیر است.
- کاربر به نشانی اپلیکیشن یا وبسایتی که میخواهد دسترسی یابد میرود که اینجا ارائهدهنده سرویس نامیده میشود.
- ارائهدهنده سرویس یک توکن به سیستم SSO یعنی ارائهدهنده هویت ارسال میکند که شامل اطلاعاتی در مورد کاربر از قبیل نشانی ایمیل میشود و برای احراز هویت کاربر استفاده میشود.
- ارائهدهنده هویت ابتدا بررسی میکند آیا کاربر قبلاً احراز هویت شده یا نه و در صورتی که چنین باشد امکان دسترسی به اپلیکیشن ارائهدهنده سرویس را فراهم ساخته و به گام پنجم میرود.
- اگر کاربر قبلاً وارد نشده باشد، با ارائه اطلاعات احراز هویت که از سوی ارائهدهنده هویت فراهم آمده از وی خواسته میشود که این کار را انجام دهد. این اطلاعات میتوانند صرفاً یک نام کاربری و رمز عبور باشند و یا شامل اطلاعات دیگری از قبیل رمزهای عبور یک بار مصرف نیز باشند.
- زمانی که ارائهدهنده هویت، صحت اطلاعات احراز را تأیید کرد، یک توکن به ارائهدهنده سرویس بازگشت میدهد که نشانگر تأیید شدن فرایند احراز هویت است.
- توکنی که از سوی ارائهدهنده سرویس دریافت میشود، بر اساس رابطه اعتمادی تأیید میشود که بین ارائهدهنده سرویس و ارائهدهنده هویت در مرحله پیکربندی اولیه برقرار شده است.
- کاربر امکان دسترسی به ارائهدهنده سرویس را پیدا میکند.
زمانی که کاربر تلاش کند به وبسایت دیگری دسترسی یابد، این وبسایت جدید رابطه اعتماد مشابهی با SSO برقرار کرده باشد تا گردش کار احراز هویت به روش مشابهی انجام شود.
توکن SSO چیست ؟
توکن SSO یک مجموعه دادهها یا اطلاعات است که در طی فرایند SSO از یک سیستم به سیستم دیگر ارسال میشود. این دادهها میتوانند صرفاً شامل نشانی ایمیل و اطلاعاتی در مورد سیستم ارسالکننده توکن باشند. توکنها باید به صورت دیجیتالی برای گیرنده توکن امضا شوند تا تأیید شود که توکن از یک منبع مورد اعتماد میآید. گواهینامهای که برای این امضای دیجیتالی استفاده میشود در طی فرایند پیکربندی اولیه مبادله شده است.
آیا SSO امن است؟
پاسخ به این سؤال بستگی به موارد مختلفی دارد. SSO از جهات مختلف میتواند موجب ارتقای امنیت بشود. یک راهکار «ثبت نام منفرد» (single sign-on) اجازه میدهد که مدیریت رمز عبور و نام کاربری برای کاربران و همچنین مدیران به صورت سادهتری انجام یابد. بدین ترتیب دیگر لازم نیست کاربران رمزهای عبور مختلف را ذخیره کرده یا به خاطر بسپارند و تنها یک رمز عبور منفرد پیچیده را به خاطر میسپارند. SSO در اغلب موارد به کاربران امکان میدهد که سریعتر به اپلیکیشنهایشان دسترسی یابند.
SSO همچنین موجب میشود که زحمتهای بخش پشتیبانی هر شرکت برای کمک به کاربرانی که رمز عبورشان را فراموش کردهاند کاهش یابد. مدیران میتوانند الزاماتی مانند پیچیدگی رمز عبور و احراز هویتهای چندمرحلهای (MFA) را به روش متمرکزی مدیریت کنند. همچنین مدیران میتوانند در صورت ترک سازمان از سوی یک کارمند با سرعت بالاتری دسترسیهای وی را قطع کنند.
ثبت نام منفرد برخی معایب نیز دارد. برای نمونه ممکن است بخواهید برخی اپلیکیشنها به روش محافظهکارانهتری عمل کنند. به این جهت بهتر است یک راهکار SSO انتخاب شود که این امکان را در اختیار شما قرار میدهد مثلاً پیش از ورود کاربر به یک اپلیکیشن خاص یک عامل احراز هویت دیگر نیز بخواهد یا این که پیش از دسترسی کاربر به یک شبکه امن از دسترسی وی به برخی اپلیکیشنهای خاص جلوگیری کند.
شیوه پیادهسازی SSO چیست ؟
خصوصیات شیوه پیادهسازی یک راهکار SSO تا حدود زیادی به نوع راهکاری که انتخاب میکنید وابسته است. اما مراحل کار هر چه که باشد، باید اطمینان پیدا کنید که اهداف و ایدههای روشنی در مورد پیادهسازی چنین راهکاری دارید. برای نمونه باید پاسخ سؤالات زیر را یافته باشید.
- انواع متفاوت کاربرانی که به آنها خدمت میدهید کدام هستند و الزاماتشان چیست؟
- آیا به دنبال یک راهکار داخل سازمانی هستید یا یک راهکاری ابری برای شما مناسب است؟
- آیا راهکاری که انتخاب کردهاید همراه با رشد نیازها و مقیاسبندی سازمانتان رشد خواهد کرد؟
- چه ویژگیهایی نیاز دارید تا مطمئن شوید که تنها کاربران معتمد میتوانند وارد شوند. MFA، احراز هویت تطبیقی، اعتماد بر مبنای دستگاه، وایت لیست کردن نشانی IP و غیره از جمله این ویژگیها هستند.
- با چه سیستمهایی تجمیع خواهد شد؟
- آیا نیاز به دسترسی API دارید؟
سیستم مناسب SSO چه ویژگیهایی دارد؟
نکته مهم این است که تفاوت بین SSO و سیستمهای مدیریت رمز عبور را بدانید. این سیستمها نیز گاهی SSO نامیده میشوند که اختصاری برای عبارت «ثبت نام مشابه» (Same Sign-on) است. در سیستمهای مدیریت رمز عبور شما یک نام کاربری و رمز عبور واحد دارید، اما هر بار که به اپلیکیشن یا وبسایت دیگری مراجعه میکنید باید مجدداً آن را وارد نمایید. سیستم مدیریت رمز عبور تنها کاری که انجام میدهد این است که رمز عبور شما را برای اپلیکیشنهای مختلف نگهداری میکند و در مواقع لازم آنها را به جای شما وارد میکند. هیچ رابطه اعتمادی بین اپلیکیشن و سیستم مدیریت رمز عبور وجود ندارد.
از سوی دیگر در SSO پس از این که به وسیله راهکار SSO وارد شدید، میتوانید به همه اپلیکیشنها و وبسایتهای تأیید شده از سوی راهکار بدون نیاز به ورود مجدد دسترسی داشته باشید. این موارد شامل اپلیکیشنهای ابری و همچنین اپلیکیشنهای سازمانی هستند.
فرق بین نرمافزار SSO و راهکار SSO چیست ؟
هنگامی که به بررسی گزینههای مختلف SSO میپردازید، ممکن است متوجه شوید که گاهی اوقات از آنها به نام نرمافزار SSO و گاهی با عنوان راهکار SSO یاد میشود. در اغلب موارد این تفاوت از شیوه دستهبندی گزینهها از سوی سازمانها ناشی میشود. نرمافزار چیزی است که روی یک سیستم نصب میشود. نرمافزار در واقع برای انجام برخی وظایف خاص و نه بیشتر طراحی شده است. اما عنوان راهکار نشان میدهد که امکان بسط یا سفارشیسازی ظرفیتهای محصول اصلی وجود دارد. یک ارائهدهنده ممکن است به شرکتی ارجاع بدهد که راهکار تولیدی را میزبانی میکند.
آیا انواع مختلفی از SSO وجود دارند؟
زمانی که بحث در مورد SSO است، اصطلاحات جدید زیادی وجود دارد که باید بلد باشید.
- مدیریت بخشی هویت (FIM)
- OAuth (امروزه نسخه دوم آن مطرح است)
- اتصال OpenID (OIDC)
- زبان نشانهگذاری دسترسی امنیتی (SAML)
- ثبت نام مشابه (SSO)
SSO در واقع بخشی از یک مفهوم بزرگتر به نام «مدیریت بخشی هویت» (Federated Identity Management) است و از این رو گاهی اوقات SSO به نام «SSO بخشی» نیز نامیده میشود. FIM در واقع به رابطه اعتماد ایجاد شده بین دو یا چند دامنه یا سیستمهای مدیریت هویت اشاره دارد. SSO در اغلب موارد یک ویژگی است که درون معماری FIM ارائه میشود.
OAuth 2.0 یک فریمورک خاص است که آن را نیز میتوان بخشی از معماری FIM در نظر گرفت. OAuth روی ایجاد امکان اشتراک اطلاعات هویت کاربر میان دامنههای مختلف بر مبنای رابطه اعتماد استوار است.
اتصال OpenID یا به اختصار OIDC یک لایه احراز هویت است که بر مبنای OAuth 2.0 ساخته شده تا کارکرد Single Sign-on را عرضه کند.
«زبان نشانهگذاری دسترسی امنیتی» یا به اختصار SAML یک استاندارد باز است که برای عرضه کارکرد SSO طراحی شده است.
این موارد را میتوانید در نمودار زیر به طور خلاصه مشاهده کنید.
منظور از نرمافزار SSO به عنوان یک سرویس چیست؟
دقیقاً مانند هر اپلیکیشن دیگری که امروزه روی اینترنت اجرا میشود، کارکرد SSO نیز میتواند به فضای ابری جابجا شود. پلتفرمهای مختلفی امروزه سرویسهای SSO را بر روی کلود و به شکل SaaS عرضه میکنند.
منظور از SSO اپ به اپ چیست؟
SSO بین اپلیکیشن هنوز به یک استاندارد تبدیل نشده است. در واقع این اصطلاحی است که برای ارسال هویت یک فرد از یک اپلیکیشن به اپلیکیشن دیگر درون یک اکوسیستم منفرد استفاده میشود. این فرایند تا حدودی شبیه OAuth 2.0 است اما یک روش یا پروتکل استاندارد محسوب نمیشود و در حال حاضر صرفاً از سوی SAPCloud مورد استفاده قرار میگیرد.
مزیت استفاده از SAML برای SSO چیست ؟
SAML تنها استانداردی است که هم از احراز هویت (authentication) و هم احراز دسترسی (authorization) پشتیبانی میکند. این بدان معنی است که کاربران نه تنها میتوانند با استفاده از ترکیب شناسه/رمز عبور خود لاگین کنند، بلکه میتوانند پروفایل، نقشها و مجوزهای خود را نیز از طریق همین پروتکل به اشتراک بگذارند.
SAML علاوه بر همه گزینههای دیگر کنترل بیشتری در اختیار شرکتها قرار میدهد تا با پشتیبانی از امضا کردن و رمزگذاری دادهها از هر دو سمت ارائهدهنده سرویس و ارائهدهنده احراز هویت، لاگینهای خود را به مراتب امنتر سازند. بنابراین در صورت نیاز میتوان دادهها را در کل فرایند رمزنگاری کرد و هیچ حملهای نمیتواند آنها را رمزگشایی کند، مگر این که از قبل به هر دو کلید خصوصی سمت سرویس و احراز هویت دسترسی داشته باشد. این پروتکل در سال 2005 معرفی شده و از این نظر پیادهسازیهای زیادی برای سیستمها و زبانهای مختلف عرضه شده است.
گردش کار کاربر در SSO-های مبتنی بر SAML بسیار شبیه انتقال دادهها در درخواستهای HTTP-Redirect و HTTP-POST است.
فرایند کار چنین است:
- کاربر درخواست آغاز SSO را به ارائهدهنده سرویس میدهد.
- ارائهدهنده سرویس یک درخواست احراز هویت رمزگذاری شده base64 ایجاد کرده و به ارائهدهنده هویت ارسال میکند.
- ارائهدهنده هویت درخواست احراز را دریافت کرده، تأیید کرده و از کاربر میخواهد که احراز (لاگین) کند.
- ارائهدهنده هویت فرم XHTML را به همراه پاسخ رمزگذاری شده base64 به کاربر ارسال میکند.
- کاربر پاسخ SAML را به ارائهدهنده سرویس ارسال میکند.
- ارائهدهنده سرویس پاسخ SAML را تأیید کرده و کاربر را به منبع هدف ریدایرکت میکند.
پیادهسازی SSO مبتنی بر SAML
چنان که در بخش قبل دیدیم برای پیادهسازی SSO مبتنی بر SAML به دو «نقطه انتهایی» (endpoint) نیاز داریم.
- یک نقطه انتهایی اقدام به ساخت درخواست احراز هویت کرده و کاربر را به فرم لاگین ریدایرکت کرده و دادههای درخواست لاگین را که به صورت base64 رمزگذاری شده ارسال میکند.
- نقطه انتهایی دیگر یک پاسخ SAML را پس از موفقیت فرایند لاگین پذیرفته و دریافت میکند.
شیوه انتقال دادهها از یک موجودیت به موجودیت دیگر به سه روش میتواند باشد:
- اتصال HTTP-Redirect دادهها را به شکل پارامتر دریافتی بستهبندی میکند.
- اتصال HTTP-Post دادهها را به شکل درخواست HTTP ارسال میکند. این روش معمولاً از طریق ساخت یک فرم XHTML انجام میشود.
هیچ دخالتی از سوی پروتکل HTTP از سمت کاربر یا مرورگر صورت نمیگیرد، بلکه یک اتصال مستقیم بین دو نقطه انتهایی صورت میگیرد.
درخواستهای احراز هویت به طور معمول با استفاده از اتصال HTTP-Redirect یا HTTP-Post ارسال میشوند زیرا payload دادهها کم است. اما از آنجا که پاسخ SAML معمولاً برای قرار گرفتن در یک URL بیش از حد بزرگ است، بهتر است از اتصال HTTP-Post برای انتقال دادههای پاسخ SAML استفاده شود.
درخواست احراز هویت معمولاً چیزی مانند زیر است:
from xml.etree import cElementTree from datetime import datetime as dt from django.http.response import HttpResponseRedirect from base64 import b64encode def signin(request): if not request.session.session_key: request.session.create() session_key = request.session.session_key identity_provider_url = 'https://identity-provider.com/sso/saml' provider_entity_id = 'https://service-provider.com/metadata' assertion_consumer_service_url = 'https://service-provider.com/acs' root = cElementTree.Element('samlp:AuthnRequest', attrib={ 'xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol', 'xmlns:saml': 'urn:oasis:names:tc:SAML:2.0:assertion', 'ProtocolBinding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', 'Version': '2.0', 'ID': session_key, 'ProviderName': provider_entity_id, 'IssueInstant': dt.now().isoformat(), 'Destination': identity_provider_url, 'AssertionConsumerServiceURL': assertion_consumer_service_url }) issuer = cElementTree.SubElement( root, 'saml:Issuer', text='http://sp.example.com/demo1/metadata.php' ) name_id_policy = cElementTree.SubElement( root, 'samlp:NameIDPolicy', attrib={ 'Format': 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', 'AllowCreate': 'true' } ) authentication_context = cElementTree.SubElement( root, 'samlp:RequestedAuthnContext', attrib={ 'Comparison': 'exact' } ) authentication_context_class_ref = cElementTree.SubElement( authentication_context, 'saml:AuthnContextClassRef', text='urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport' ) authentication_request = cElementTree.tostring(root, encoding='utf-8', method='xml') base64_encoded_authentication_request = b64encode(authentication_request) return HttpResponseRedirect(f'{identity_provider_url}?AuthNRequest={base64_encoded_authentication_request}')
پاسخ SAML هم به طور معمول مانند زیر است:
import binascii from signxml import XMLVerifier from django.http.response import HttpResponseBadRequest, HttpResponse, HttpResponseNotFound from django.contrib.auth import login from django.contrib.auth.models import User from base64 import b64decode from django.views.decorators.csrf import csrf_exempt @csrf_exempt def validate_saml_response(request): try: saml_response = request.POST['SAMLResponse'] except KeyError: return HttpResponseBadRequest() try: saml_response_xml = b64decode(saml_response) except binascii.Error: return HttpResponseBadRequest() namespaces = { 'ns1': "urn:oasis:names:tc:SAML:2.0:assertion", 'ns2': "http://www.w3.org/2000/09/xmldsig#" } xml_verifier = XMLVerifier() try: verified_xml = xml_verifier.verify( saml_response_xml, x509_cert=open('app/data/idp.crt', 'r').read()).signed_xml email = verified_xml.find('.ns1:Assertion/ns1:Subject/ns1:NameID', namespaces).text except : return HttpResponseBadRequest() try: user = User.objects.get(email=email) except User.DoesNotExist: return HttpResponseNotFound() login(request, user) return HttpResponse(f'Logged in as {user.email}
', content_type='text/html')
پیادهسازی ساده واحد احراز هویت مرکزی SSO و کلاینت در Node.js
در هسته مرکزی SSO یک سرور احراز هویت منفرد داریم که اطلاعات امنیتی از قبیل ایمیل کاربر، نام کاربری و رمز عبور را میگیرد. سیستمهای دیگر دسترسی لاگین را ارائه نمیکنند و تنها فرم احراز هویت را به طور غیرمستقیم از سرور احراز هویت میگیرند. احراز هویت غیرمستقیم با استفاده از توکن صورت میگیرد.
در این بخش از مثابه از Node.js برای کدنویسی استفاده میکنیم، اما هر نوع فناوری دیگر نیز میتواند برای پیادهسازی مفاهیم اساسی SSO استفاده شود. مراحل کار چنین است.
کاربر ابتدا درخواست دسترسی به منبع حفاظتشده سیستم مصرفکننده SSO میدهد. مصرفکننده SSO متوجه میشود که کاربر لاگین نکرده و به سراغ سرور SSO میرود و آدرس خود را به عنوان پارامتر ارسال میکند. ما قصد داریم یک میانافزار Express.js برای بررسی این موضوع در درخواستها استفاده کنیم.
const isAuthenticated = (req, res, next) => { // simple check to see if the user is authenicated or not, // if not redirect the user to the SSO Server for Login // pass the redirect URL as current URL // serviceURL is where the sso should redirect in case of valid user const redirectURL = `${req.protocol}://${req.headers.host}${req.path}`; if (req.session.user == null) { return res.redirect( `http://sso.ankuranand.com:3010/simplesso/login?serviceURL=${redirectURL}` ); } next(); }; module.exports = isAuthenticated;
سرور احراز هویت SSO متوجه میشود که کاربر لاگین نکرده و او را به صفحه لاگین هدایت میکند.
const login = (req, res, next) => { // The req.query will have the redirect url where we need to redirect after successful // login and with sso token. // This can also be used to verify the origin from where the request has came in // for the redirection const { serviceURL } = req.query; // direct access will give the error inside new URL. if (serviceURL != null) { const url = new URL(serviceURL); if (alloweOrigin[url.origin] !== true) { return res .status(400) .json({ message: "Your are not allowed to access the sso-server" }); } } if (req.session.user != null && serviceURL == null) { return res.redirect("/"); } // if global session already has the user directly redirect with the token if (req.session.user != null && serviceURL != null) { const url = new URL(serviceURL); const intrmid = encodedId(); storeApplicationInCache(url.origin, req.session.user, intrmid); return res.redirect(`${serviceURL}?ssoToken=${intrmid}`); } return res.render("login", { title: "SSO-Server | Login" }); };
به عنوان یک لایه امنیتی بیشتر بررسی میکنیم آیا serviceURL که به صورت کوئری به سرور SSO ارائه شده برای استفاده از این سرور ثبت شده است یا نه.
const alloweOrigin = { "http://consumer.ankuranand.in:3020": true, "http://consumertwo.ankuranand.in:3030": true, "http://test.tangledvibes.com:3080": true, "http://blog.tangledvibes.com:3080": fasle, };
کاربر نام کاربری و رمز عبور را وارد کرده و از طریق درخواست لاگین تحویل میدهد.
سرور احراز هویت SSO اطلاعات کاربر را بررسی کرده و یک نشست بین کاربر و سرور احرار هویت ایجاد میکند. این نشست یک «نشست سراسری» (global session) نامیده شده و یک توکن احراز هویت ایجاد میشود. توکن احراز هویت یک رشته از کاراکترهای تصادفی است. روش تولید آن فعلاً اهمیتی ندارد، تا زمانی که تکراری نباشد، امکان جعل کردن آن وجود نخواهد داشت.
سرور احراز هویت SSO توکن احراز هویت را گرفته و به نشانی درخواست اولیه میرود.
const doLogin = (req, res, next) => { // do the validation with email and password // but the goal is not to do the same in this right now, // like checking with Datebase and all, we are skiping these section const { email, password } = req.body; if (!(userDB[email] && password === userDB[email].password)) { return res.status(404).json({ message: "Invalid email and password" }); } // else redirect const { serviceURL } = req.query; const id = encodedId(); req.session.user = id; sessionUser[id] = email; if (serviceURL == null) { return res.redirect("/"); } const url = new URL(serviceURL); const intrmid = encodedId(); storeApplicationInCache(url.origin, id, intrmid); return res.redirect(`${serviceURL}?ssoToken=${intrmid}`); };
نکتههای امنیتی مهم
- همیشه توکن را به عنوان یک توکن میانجی در نظر گرفته و دادههای واقعی را با استفاده از آن مبادله کنید.
- اگر از JWT به عنوان توکن میانجی استفاده میکنید، هیچ وقت دادههای حیاتی را از طریق این JWT مبادله نکنید.
مصرفکننده SSO توکن را رفته و احراز هویت سرور SSO مراجعه میکند تا اعتبار آن را بررسی کند. سرور SSO توکن را تأیید کرده و آن را با اطلاعات کاربر به مصرفکننده SSO بازگشت میدهد. مصرفکننده SSO از این توکن برای ایجاد یک نشست با کاربر استفاده میکند. این نشست به نام «نشست لوکال» (local session) خوانده میشود.
در ادامه کد مختصر میانافزار مصرفکننده SSO را درون اپلیکیشن مصرفکننده SSO میبینید که با استفاده از اکسپرس ساخته شده است.
const ssoRedirect = () => { return async function(req, res, next) { // check if the req has the queryParameter as ssoToken // and who is the referer. const { ssoToken } = req.query; if (ssoToken != null) { // to remove the ssoToken in query parameter redirect. const redirectURL = url.parse(req.url).pathname; try { const response = await axios.get( `${ssoServerJWTURL}?ssoToken=${ssoToken}`, { headers: { Authorization: "Bearer l1Q7zkOL59cRqWBkQ12ZiGVW2DBL" } } ); const { token } = response.data; const decoded = await verifyJwtToken(token); // now that we have the decoded jwt, use the, // global-session-id as the session id so that // the logout can be implemented with the global session. req.session.user = decoded; } catch (err) { return next(err); } return res.redirect(`${redirectURL}`); } return next(); }; };
پس از آن که درخواست از سمت مصرفکننده آمد، این سرور SSO توکن را بررسی میکند تا متوجه شود آیا توکن موجود است و منقضی نشده است. به این ترتیب توکن با موفقیت تأیید میشود.
در این مورد سرور SSO پس از موفق بودن تأیید یک JWT امضاشده با اطلاعات کاربر بازگشت میدهد.
const verifySsoToken = async (req, res, next) => { const appToken = appTokenFromRequest(req); const { ssoToken } = req.query; // if the application token is not present or ssoToken request is invalid // if the ssoToken is not present in the cache some is // smart. if ( appToken == null || ssoToken == null || intrmTokenCache[ssoToken] == null ) { return res.status(400).json({ message: "badRequest" }); } // if the appToken is present and check if it's valid for the application const appName = intrmTokenCache[ssoToken][1]; const globalSessionToken = intrmTokenCache[ssoToken][0]; // If the appToken is not equal to token given during the sso app registraion or later stage than invalid if ( appToken !== appTokenDB[appName] || sessionApp[globalSessionToken][appName] !== true ) { return res.status(403).json({ message: "Unauthorized" }); } // checking if the token passed has been generated const payload = generatePayload(ssoToken); const token = await genJwtToken(payload); // delete the itremCache key for no futher use, delete intrmTokenCache[ssoToken]; return res.status(200).json({ token }); };
نکات امنیتی مهم
درون سرور SSO هر اپلیکیشن که در ادامه از آن برای احراز هویت استفاده خواهد کرد باید ثبت شده باشد و نوعی هدر تأیید درمان ایجاد درخواست به آنها داده شود. به این ترتیب امنیت بهتری بین مصرفکننده و سرور برقرار میشود.
امکان تولید فایل rsa خصوصی و عمومی متفاوت نیز برای هر اپلیکیشن وجود دارد که اجازه میدهد هر کدام از اپلیکیشنها JWT خودشان را با کلید عمومی مربوطه در سمت مصرفکننده تأیید کنند.
همچنین امکان تعریف سیاستهایی در سطح اپلیکیشن در یک مکان متمرکز وجود دارد.
const userDB = { "info@ankuranand.com": { password: "test", userId: encodedId(), // incase you dont want to share the user-email. appPolicy: { sso_consumer: { role: "admin", shareEmail: true }, simple_sso_consumer: { role: "user", shareEmail: false } } } };
پس از آن که کاربر با موفقیت لاگین کرد، یک نشست با سرور احراز هویت SSO و هر زیرسیستم مصرفکننده ایجاد میشود. نشست ایجاد شده بین کاربر و سرور احراز هویت SSO به نام نشست سراسری خوانده میشود. نشست ایجاد شده بین کاربر و هر زیرسیستم مصرفکننده به نام نشست لوکال نامیده میشود. پس از آن که نشست لوکال ایجاد شد، کاربر میتواند به منابع حفاظتشده زیرسیستم مصرفکننده دسترسی پیدا کند.
اینک نشست لوکال و نشست سراسری هر دو ایجاد شدهاند. در ادامه جمعبندی کارکردهایی که برای سرور SSO و کلاینت SSO پیادهسازی کردیم، ارائه شده است.
مصرفکننده SSO
- زیرسیستم مصرفکننده SSO وارد درخواست کاربر نمیشود برای احراز هویت به سراغ سرور SSO میرود.
- توکن ارسالی از سوی سرور احراز هویت SSO دریافت میشود.
- با سرور SSO ارتباط گرفته و اعتبار توکن را بررسی میکند.
- یک JWT دریافت کرده و آن را با استفاده از کلید عمومی بررسی میکند.
- یک نشست لوکال برقرار میکند.
سرور SSO
- اطلاعات لاگین کاربر را تأیید میکند.
- یک نشست سراسری ایجاد میکند.
- یک توکن احراز هویت میسازد.
- توکن را از طریق ارتباط با کلاینت SSO ارسال میکند.
- اعتبار توکن کلاینت SSO را تأیید میکند.
- یک JWT به همراه اطلاعات کاربر ارسال میکند.
سخن پایانی
پروتکل SSO مدت زیادی است که معرفی شده است. در این نوشته با تاریخچه، انواع، کاربردها و مزیت و معایب آن آشنا شدیم. این فناوری همچنان در حال تکامل است و امروزه شاهد هستیم که دستگاه تلفن همراه کاربران به عنوان کلید احراز هویت آنها برای لاگین کردن در پلتفرمهای مختلف مورد استفاده قرار میگیرد. با این حال این فناوری نیز برخی معایب از نظر امنیتی و رعایت حریم خصوصی دارد و از هجمه انتقادات به دور نمانده است. از این رو باید در زمان تصمیمگیری برای استفاده از آن با چشم باز و با رعایت همه جوانب تصمیمگیری کنید.
==