ओरी हाइड्रा एक लोकप्रिय ओपन-सोर्स OAuth2 और OpenID कनेक्ट सर्वर है जो अनुप्रयोगों के लिए सुरक्षित प्रमाणीकरण और प्राधिकरण प्रदान करता है। स्केलेबल और परफ़ॉर्मेंट OAuth2 सर्वर के निर्माण में प्रमुख चुनौतियों में से एक दृढ़ता परत का प्रबंधन करना है, जिसमें डेटाबेस से डेटा संग्रहीत करना और पुनर्प्राप्त करना शामिल है।
एक लोकप्रिय सेवा प्रदाता ने उच्च लोड पर अपने ऑथ सिस्टम में प्रदर्शन को अनुकूलित करने के लिए ओरी से संपर्क किया था। वे अक्सर चरम समय (600लॉगिन/सेकंड से अधिक) के दौरान प्राधिकरण अनुदान की भारी आमद से निपटने के लिए संघर्ष करते थे। दूसरे समाधान की तलाश में, उन्होंने ओरी हाइड्रा का मूल्यांकन करना शुरू कर दिया, यह जांच करते हुए कि क्या यह अनुदान की इस राशि को संभाल सकता है। टीम तक पहुंचने के बाद, हमने ओरी हाइड्रा को पहले से कहीं अधिक तेज़ और अधिक स्केलेबल बनाने के लिए समग्र प्रदर्शन में सुधार करने के तरीकों की जांच शुरू कर दी। सफलता की कुंजी डेटाबेस में लेखन ट्रैफ़िक को कम करने के लिए हाइड्रा की दृढ़ता परत के कुछ हिस्सों को फिर से इंजीनियर करना था, जो एक क्षणिक OAuth2 प्रवाह की ओर बढ़ रहा था।
इस कार्य के मुख्य भागों में से एक क्षणिक OAuth2 प्रवाह स्थिति के एक बड़े हिस्से को स्थानांतरित करना था, जिसका सर्वर से क्लाइंट तक OAuth2 प्रवाह में शामिल तीन पक्षों के बीच आदान-प्रदान किया जाता है। डेटाबेस में क्षणिक स्थिति को बनाए रखने के बजाय, स्थिति को अब रीडायरेक्ट यूआरएल में एईएडी-एन्कोडेड कुकीज़ या एईएडी-एन्कोडेड क्वेरी पैरामीटर के रूप में पार्टियों के बीच पारित किया जाता है। AEAD का मतलब संबंधित डेटा के साथ प्रमाणित एन्क्रिप्शन है, जिसका अर्थ है कि डेटा गोपनीय है और किसी गुप्त (सममित) कुंजी को जाने बिना उसके साथ छेड़छाड़ नहीं की जा सकती है।
अंतिम सहमति मिलने पर प्रवाह केवल एक बार डेटाबेस में जारी रहता है।
इस बदलाव के कई फायदे हैं. सबसे पहले, यह डेटाबेस में संग्रहीत किए जाने वाले डेटा की मात्रा को कम करता है, जिसके परिणामस्वरूप लेखन ट्रैफ़िक कम हो जाता है। दूसरा, यह प्रवाह तालिका पर कई सूचकांकों की आवश्यकता को समाप्त करता है जो पहले विनिमय के दौरान उपयोग किए जाते थे।
OAuth2 प्रवाह का प्रासंगिक हिस्सा जिसे हम अनुकूलित करना चाहते थे वह क्लाइंट (उपयोगकर्ता की ओर से कार्य करना), हाइड्रा (Ory का OAuth2 प्राधिकरण सर्वर), और लॉगिन और सहमति स्क्रीन के बीच एक आदान-प्रदान है। जब कोई ग्राहक प्राधिकरण कोड अनुदान के माध्यम से प्राधिकरण कोड का अनुरोध करता है, तो उपयोगकर्ता को प्रमाणित करने के लिए पहले लॉगिन यूआई पर और फिर उपयोगकर्ता के डेटा (जैसे ईमेल पता या प्रोफ़ाइल जानकारी) तक पहुंच प्रदान करने के लिए सहमति यूआई पर रीडायरेक्ट किया जाएगा।
नीचे एक्सचेंज का अनुक्रम आरेख है। ध्यान दें कि प्रत्येक यूआई को यूआरएल पैरामीटर (चरण 3 और 12) के हिस्से के रूप में एक CHALLENGE
मिलती है और फिर अधिक जानकारी प्राप्त करने के लिए पैरामीटर के रूप में इस CHALLENGE
उपयोग करता है (चरण 4 और 13)। अंत में, दोनों यूआई या तो उपयोगकर्ता के अनुरोध को स्वीकार करते हैं या अस्वीकार करते हैं, जो आमतौर पर यूआई के साथ उपयोगकर्ता की बातचीत पर आधारित होता है (चरण 6 से 8 और 15 से 17 तक)। यह एपीआई अनुबंध ओरी हाइड्रा को हेडलेस रखता है और कस्टम यूआई से अलग रखता है।
डेटाबेस पहुंच को कम करने के लिए अब हम LOGIN_CHALLENGE
, LOGIN_VERIFIER
, CONSENT_CHALLENGE
, और CONSENT_VERIFIER
AEAD-एन्कोडेड प्रवाह के रूप में पास करते हैं। इस तरह, हम प्रासंगिक स्थिति को पारित करने के लिए OAuth2 प्रवाह में शामिल पार्टियों पर भरोसा करते हैं।
पहले | बाद |
---|---|
लॉगिन और सहमति चुनौतियाँ और सत्यापनकर्ता डेटाबेस में संग्रहीत यादृच्छिक यूयूआईडी हैं। | लॉगिन और सहमति चुनौतियाँ और सत्यापनकर्ता AEAD-एन्कोडेड प्रवाह हैं। |
यूआई से अनुरोध को स्वीकार या अस्वीकार करने में विशिष्ट चुनौती के लिए डेटाबेस लुकअप शामिल होता है। | यूआई से अनुरोध को स्वीकार या अस्वीकार करने में चुनौती में प्रवाह को डिक्रिप्ट करना और सत्यापनकर्ता के हिस्से के रूप में एक अद्यतन प्रवाह उत्पन्न करना शामिल है। |
चूँकि Ory Hydra खुला स्रोत है, आप Ory GitHub रिपॉजिटरी में कोड परिवर्तनों की समीक्षा कर सकते हैं। यह प्रासंगिक प्रतिबद्धता है.
यहां वह जगह है जहां हम विशिष्ट चुनौतियों और सत्यापनकर्ताओं में प्रवाह को एन्कोड करते हैं:
// ToLoginChallenge converts the flow into a login challenge. func (f *Flow) ToLoginChallenge(ctx context.Context, cipherProvider CipherProvider) (string, error) { return flowctx.Encode(ctx, cipherProvider.FlowCipher(), f, flowctx.AsLoginChallenge) } // ToLoginVerifier converts the flow into a login verifier. func (f *Flow) ToLoginVerifier(ctx context.Context, cipherProvider CipherProvider) (string, error) { return flowctx.Encode(ctx, cipherProvider.FlowCipher(), f, flowctx.AsLoginVerifier) } // ToConsentChallenge converts the flow into a consent challenge. func (f *Flow) ToConsentChallenge(ctx context.Context, cipherProvider CipherProvider) (string, error) { return flowctx.Encode(ctx, cipherProvider.FlowCipher(), f, flowctx.AsConsentChallenge) } // ToConsentVerifier converts the flow into a consent verifier. func (f *Flow) ToConsentVerifier(ctx context.Context, cipherProvider CipherProvider) (string, error) { return flowctx.Encode(ctx, cipherProvider.FlowCipher(), f, flowctx.AsConsentVerifier) }
पर्सिस्टर (हमारा डेटाबेस रिपॉजिटरी) में हम चुनौती में निहित प्रवाह को डिकोड करते हैं। उदाहरण के लिए, सहमति चुनौती से निपटने के लिए कोड यहां दिया गया है:
func (p *Persister) GetFlowByConsentChallenge(ctx context.Context, challenge string) (*flow.Flow, error) { ctx, span := prTracer(ctx).Tracer().Start(ctx, "persistence.sql.GetFlowByConsentChallenge") defer span.End() // challenge contains the flow. f, err := flowctx.Decode[flow.Flow](ctx, prFlowCipher(), challenge, flowctx.AsConsentChallenge) if err != nil { return nil, errorsx.WithStack(x.ErrNotFound) } if f.NID != p.NetworkID(ctx) { return nil, errorsx.WithStack(x.ErrNotFound) } if f.RequestedAt.Add(p.config.ConsentRequestMaxAge(ctx)).Before(time.Now()) { return nil, errorsx.WithStack(fosite.ErrRequestUnauthorized.WithHint("The consent request has expired, please try again.")) } return f, nil }
आइए अनुकूलन के बिना कोड की तुलना में परिवर्तनों के प्रभाव को देखें:
प्रवाह अब बहुत तेज़ है और डेटाबेस से कम बातचीत करता है।
hydra_oauth2_flow
टेबल पर एक नया इंडेक्स पेश करके, हम PostgreSQL पर थ्रूपुट बढ़ाने और CPU उपयोग को कम करने में सक्षम थे। नीचे दिया गया स्क्रीनशॉट बेहतर सूचकांकों के बिना बेंचमार्क के निष्पादन को दिखाता है जहां सीपीयू का उपयोग 100% तक बढ़ जाता है, और बेहतर सूचकांकों के साथ, जहां सीपीयू का उपयोग 10% से नीचे रहता है।
नए जोड़े गए सूचकांकों के साथ, सीपीयू उपयोग (हरी पट्टियाँ) हटा दी जाती हैं, जिससे बफ़रलॉक और संबंधित समस्याओं की संभावना कम हो जाती है:
कोड और डेटाबेस परिवर्तनों ने डेटाबेस में कुल राउंडट्रिप को 4-5x (कैशिंग की मात्रा के आधार पर) कम कर दिया और डेटाबेस राइट्स को लगभग 50% कम कर दिया।
निम्नलिखित विशिष्टताओं के साथ Microsoft Azure पर नए कार्यान्वयन को बेंचमार्क करना:
सेवाएं | विन्यास | कुल अधिकतम SQL कनेक्शन | टिप्पणियाँ |
---|---|---|---|
ओरी हाइड्रा सहमति ऐप OAuth2 क्लाइंट ऐप rakyll/hey (http बेंचमार्क टूल) | 3x मानक_D32as_v4; दक्षिण मध्य यूएस 5x मानक_D8s_v3; दक्षिण मध्य यू.एस | 512 | प्रत्येक वीएम उल्लिखित सभी प्रक्रियाओं को चलाता है। |
HA कॉन्फ़िगरेशन में PostgreSQL 14 | मेमोरी अनुकूलित, E64ds_v4, 64 vCores, 432 GiB रैम, 32767 GiB स्टोरेज; दक्षिण मध्य यू.एस | | रैम सीपीयू को मात देती है। |
ओरी चरम पर 1090 लॉगिन प्रति सेकंड और उपरोक्त कॉन्फ़िगरेशन में लगातार 800 लॉगिन/सेकंड तक प्रदर्शन कर सकता है। यह प्रवाह को स्टेटलेस बनाकर और अक्सर उपयोग की जाने वाली क्वेरी में सूचकांकों को अनुकूलित करके संभव है।
ओरी टीम द्वारा किए गए प्रदर्शन अनुकूलन कार्य के परिणामस्वरूप हाइड्रा के प्रदर्शन और स्केलेबिलिटी में महत्वपूर्ण सुधार हुआ है। डेटाबेस में लेखन ट्रैफ़िक को कम करके और कोडबेस और निर्भरता में सुधार करके, हाइड्रा अब पहले से कहीं अधिक तेज़ और अधिक प्रतिक्रियाशील है। सूचकांकों में सुधार करके, हाइड्रा अब उदाहरणों की संख्या के साथ अधिक कुशलता से मापता है।
भविष्य में, हम और भी अधिक ट्रैफ़िक संभालने के लिए Ory के सॉफ़्टवेयर को अनुकूलित करना जारी रखेंगे। हमारा मानना है कि डेटा मॉडल अनुकूलन के साथ एकल PostgreSQL नोड पर 5x अधिक थ्रूपुट प्राप्त करना संभव है।
यदि आप OAuth2 सर्वर का निर्माण कर रहे हैं, तो हम Ory के पूरी तरह से प्रमाणित OpenID कनेक्ट और OAuth2 कार्यान्वयन को आज़माने की अत्यधिक अनुशंसा करते हैं: Ory OAuth2 - ओपन सोर्स Ory Hydra पर आधारित वैश्विक Ory नेटवर्क पर चलने वाली हमारी पूरी तरह से प्रबंधित सेवा - पहले से ही वर्णित अनुकूलन का उपयोग करती है इस आलेख में और इसे सेट करने में केवल कुछ मिनट लगते हैं!
यहाँ भी प्रकाशित किया गया है.