OpenID Connect: дотоод програмуудыг захиалгаас стандарт руу шилжүүлэх

Хэдэн сарын өмнө би олон зуун дотоод хэрэглээний программуудын хандалтыг удирдах OpenID Connect серверийг хэрэгжүүлж байсан. Өөрсдийн бүтээн байгуулалтаас бага хэмжээгээр тохиромжтой, бид нийтээр хүлээн зөвшөөрөгдсөн стандарт руу шилжсэн. Төвлөрсөн үйлчилгээгээр дамжуулан хандах нь нэгэн хэвийн үйл ажиллагааг ихээхэн хөнгөвчлөх, зөвшөөрлийг хэрэгжүүлэх зардлыг бууруулж, олон бэлэн шийдлүүдийг олох боломжийг олгодог бөгөөд шинийг боловсруулахдаа тархи толгойгоо гашилгахгүй. Энэ нийтлэлд би энэ шилжилтийн талаар болон бидний дүүргэж чадсан овойлтуудын талаар ярих болно.

OpenID Connect: дотоод програмуудыг захиалгаас стандарт руу шилжүүлэх

Эрт дээр үед... Энэ бүхэн хэрхэн эхэлсэн

Хэдэн жилийн өмнө гар аргаар хянах дотоод программууд хэтэрхий олон байхад бид компани дотроо хандалтыг хянах програм бичсэн. Энэ нь ажилчдын талаарх мэдээлэл бүхий өгөгдлийн санд холбогдсон энгийн Rails програм байсан бөгөөд тэнд янз бүрийн функцэд хандах хандалтыг тохируулсан. Үүний зэрэгцээ бид үйлчлүүлэгч болон зөвшөөрлийн серверийн токенуудыг шалгахад үндэслэсэн анхны SSO-г босгож, жетоныг хэд хэдэн параметр бүхий шифрлэгдсэн хэлбэрээр дамжуулж, зөвшөөрлийн сервер дээр баталгаажуулсан. Энэ нь хамгийн тохиромжтой сонголт биш байсан, учир нь дотоод програм бүр нь логикийн нэлээд давхаргыг тайлбарлах ёстой байсан бөгөөд ажилчдын мэдээллийн сан нь зөвшөөрлийн сервертэй бүрэн синхрончлогдсон байв.

Хэсэг хугацааны дараа бид төвлөрсөн зөвшөөрлийн ажлыг хялбарчлахаар шийдсэн. SSO-г тэнцвэржүүлэгч рүү шилжүүлсэн. OpenResty-ийн тусламжтайгаар токенуудыг шалгадаг, хүсэлт нь аль программ руу явж байгааг мэдэж, тэнд хандах боломж байгаа эсэхийг шалгах загварыг Луа-д нэмсэн. Энэ арга нь дотоод програмуудад хандах хандалтыг хянах ажлыг ихээхэн хялбаршуулсан - програм бүрийн кодонд нэмэлт логикийг тайлбарлах шаардлагагүй болсон. Үүний үр дүнд бид замын хөдөлгөөнийг гаднаас хаасан бөгөөд програм өөрөө зөвшөөрлийн талаар юу ч мэдэхгүй байв.

Гэсэн хэдий ч нэг асуудал шийдэгдээгүй хэвээр байв. Ажилчдын талаарх мэдээлэл шаардлагатай програмуудын талаар юу хэлэх вэ? Зөвшөөрлийн үйлчилгээнд зориулж API бичих боломжтой байсан ч дараа нь ийм програм бүрт нэмэлт логик нэмэх шаардлагатай болно. Нэмж дурдахад, бид ирээдүйд OpenSource руу орчуулах зорилготой, өөрийн дотоод зөвшөөрлийн сервер дээрээ өөрөө бичсэн програмынхаа аль нэгээс хамааралтай байдлаас ангижрахыг хүссэн. Бид өөр үед энэ тухай ярих болно. Хоёр асуудлын шийдэл нь OAuth байсан.

нийтлэг стандартад

OAuth бол ойлгомжтой, нийтээр хүлээн зөвшөөрөгдсөн зөвшөөрлийн стандарт боловч зөвхөн түүний үйл ажиллагаа хангалтгүй тул OpenID Connect (OIDC) нэн даруй авч үзэх болсон. OIDC нь өөрөө OAuth 2.0 протокол (нээлттэй зөвшөөрлийн протокол) дээр нэмэлт болгон нэвтэрсэн нээлттэй баталгаажуулалтын стандартын гурав дахь хэрэгжилт юм. Энэхүү шийдэл нь эцсийн хэрэглэгчийн талаарх мэдээллийн хомсдолтой холбоотой асуудлыг хааж, зөвшөөрлийн үйлчилгээ үзүүлэгчийг өөрчлөх боломжийг олгодог.

Гэсэн хэдий ч бид тодорхой үйлчилгээ үзүүлэгчийг сонгоогүй бөгөөд одоо байгаа зөвшөөрлийн сервертээ OIDC-тэй нэгтгэхээр шийдсэн. Энэхүү шийдвэрийг дэмжсэн нь OIDC нь эцсийн хэрэглэгчийн зөвшөөрлийн хувьд маш уян хатан байдаг. Тиймээс OIDC-ийн дэмжлэгийг таны одоогийн зөвшөөрлийн сервер дээр хэрэгжүүлэх боломжтой болсон.

OpenID Connect: дотоод програмуудыг захиалгаас стандарт руу шилжүүлэх

Бидний өөрийн OIDC серверийг хэрэгжүүлэх арга зам

1) Өгөгдлийг хүссэн хэлбэрт оруулав

OIDC-ийг нэгтгэхийн тулд одоогийн хэрэглэгчийн өгөгдлийг стандартад ойлгомжтой хэлбэрт оруулах шаардлагатай. OIDC-д үүнийг нэхэмжлэл гэж нэрлэдэг. Нэхэмжлэл нь үндсэндээ хэрэглэгчийн мэдээллийн сангийн эцсийн талбарууд юм (нэр, имэйл, утас гэх мэт). Байгаа маркийн стандарт жагсаалт, мөн энэ жагсаалтад ороогүй бүх зүйлийг заншил гэж үздэг. Тиймээс, хэрэв та одоо байгаа OIDC үйлчилгээ үзүүлэгчийг сонгохыг хүсч байвал анхаарах ёстой хамгийн эхний зүйл бол шинэ брэндүүдийг хялбархан тохируулах боломж юм.

Онцлог шинж тэмдгүүдийн бүлгийг дараах дэд бүлэгт нэгтгэсэн - Хамрах хүрээ. Зөвшөөрөл олгох үед зарим брэндийг ашиглах шаардлагагүй байсан ч тодорхой брэндүүд биш, харин хамрах хүрээ рүү хандахыг хүсдэг.

2) Шаардлагатай буцалтгүй тусламжийг хэрэгжүүлсэн

OIDC-ийн интеграцийн дараагийн хэсэг нь буцалтгүй тусламж гэж нэрлэгддэг зөвшөөрлийн төрлийг сонгох, хэрэгжүүлэх явдал юм. Сонгосон програм болон зөвшөөрлийн сервер хоорондын харилцан үйлчлэлийн цаашдын хувилбар нь сонгосон тэтгэлгээс хамаарна. Зөв тэтгэлэг сонгох жишээ схемийг доорх зурагт үзүүлэв.

OpenID Connect: дотоод програмуудыг захиалгаас стандарт руу шилжүүлэх

Анхны өргөдөлдөө бид хамгийн түгээмэл тэтгэлэг болох Зөвшөөрлийн кодыг ашигласан. Түүний бусдаас ялгаатай нь энэ нь гурван үе шаттай, i.e. нэмэлт шинжилгээнд хамрагдаж байна. Эхлээд хэрэглэгч зөвшөөрөл авах хүсэлт гаргаж, жетон - Зөвшөөрлийн кодыг хүлээн авдаг бөгөөд дараа нь энэ жетоноор аяллын тасалбартай адил хандалтын жетон хүсэлт гаргадаг. Энэхүү зөвшөөрлийн скриптийн бүх үндсэн харилцан үйлчлэл нь програм болон зөвшөөрлийн серверийн хоорондох дахин чиглүүлэлт дээр суурилдаг. Та энэ тэтгэлгийн талаар илүү ихийг уншиж болно энд.

OAuth нь зөвшөөрөл авсны дараа олж авсан хандалтын токенууд нь түр зуурынх байх ёстой бөгөөд дунджаар 10 минут тутамд өөрчлөгдөх ёстой гэсэн үзэл баримтлалыг баримталдаг. Зөвшөөрлийн код олгох нь дахин чиглүүлэлтээр дамжуулан гурван үе шаттай баталгаажуулалт бөгөөд 10 минут тутамд ийм алхамыг эргүүлэх нь нүдэнд хамгийн тааламжтай ажил биш юм. Энэ асуудлыг шийдэхийн тулд өөр нэг буцалтгүй тусламж байдаг - Refresh Token, үүнийг манай улсад ч ашигладаг. Энд бүх зүйл илүү хялбар болсон. Өөр буцалтгүй тусламжаас баталгаажуулах явцад үндсэн хандалтын токеноос гадна өөр нэгийг гаргадаг - Refresh жетоныг зөвхөн нэг удаа ашиглах боломжтой бөгөөд ашиглалтын хугацаа нь ихэвчлэн илүү урт байдаг. Энэхүү Refresh Token-ийн тусламжтайгаар үндсэн хандалтын токены TTL (Амьдрах хугацаа) дуусах үед шинэ хандалтын токен авах хүсэлт өөр тэтгэлгийн төгсгөлд ирнэ. Ашигласан Refresh Token нэн даруй тэг болж өөрчлөгдөнө. Энэхүү шалгалт нь хоёр үе шаттай бөгөөд хэрэглэгчдэд үл мэдэгдэх байдлаар далд хийж болно.

3) Өгөгдлийн гаралтын форматыг тохируулах

Сонгосон тэтгэлэг хэрэгжиж, зөвшөөрлийн ажил дууссаны дараа эцсийн хэрэглэгчийн талаарх мэдээллийг олж авахыг дурдах нь зүйтэй. OIDC нь тусдаа төгсгөлийн цэгтэй бөгөөд та хэрэглэгчийн өгөгдлийг одоогийн хандалтын токен болон шинэчлэгдсэн эсэхийг хүсэх боломжтой. Хэрэв хэрэглэгчийн өгөгдөл тийм ч их өөрчлөгддөггүй бөгөөд та одоо байгаа мэдээллийг олон удаа дагаж мөрдөх шаардлагатай бол JWT жетон гэх мэт шийдэлд хүрч болно. Эдгээр жетонуудыг мөн стандартаар дэмждэг. JWT токен нь өөрөө гурван хэсгээс бүрдэнэ: толгой хэсэг (жетоны тухай мэдээлэл), ачаалал (шаардлагатай өгөгдөл) болон гарын үсэг (гарын үсэг, жетон нь сервер гарын үсэг зурсан бөгөөд та дараа нь гарын үсгийн эх сурвалжийг шалгаж болно).

OIDC-ийн хэрэгжилтэд JWT токеныг id_token гэж нэрлэдэг. Үүнийг ердийн хандалтын токенын хамт авах боломжтой бөгөөд зөвхөн гарын үсгийг баталгаажуулах л үлдлээ. Зөвшөөрлийн сервер нь форматын олон нийтийн түлхүүр бүхий тусдаа эцсийн цэгтэй J.W.K.. Энэ тухай ярихдаа стандартад үндэслэсэн өөр нэг төгсгөлийн цэг байгааг дурдах нь зүйтэй RFC5785 OIDC серверийн одоогийн тохиргоог тусгасан. Энэ нь бүх эцсийн цэгийн хаягуудыг (гарын үсэг зурахад ашигладаг нийтийн түлхүүрийн бөгжний хаягийг оруулаад), дэмжигдсэн брэндүүд болон хамрах хүрээ, ашигласан шифрлэлтийн алгоритмууд, дэмжигдсэн тэтгэлэг гэх мэтийг агуулдаг.

Жишээлбэл, Google дээр:

{
 "issuer": "https://accounts.google.com",
 "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
 "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
 "token_endpoint": "https://oauth2.googleapis.com/token",
 "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
 "revocation_endpoint": "https://oauth2.googleapis.com/revoke",
 "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
 "response_types_supported": [
  "code",
  "token",
  "id_token",
  "code token",
  "code id_token",
  "token id_token",
  "code token id_token",
  "none"
 ],
 "subject_types_supported": [
  "public"
 ],
 "id_token_signing_alg_values_supported": [
  "RS256"
 ],
 "scopes_supported": [
  "openid",
  "email",
  "profile"
 ],
 "token_endpoint_auth_methods_supported": [
  "client_secret_post",
  "client_secret_basic"
 ],
 "claims_supported": [
  "aud",
  "email",
  "email_verified",
  "exp",
  "family_name",
  "given_name",
  "iat",
  "iss",
  "locale",
  "name",
  "picture",
  "sub"
 ],
 "code_challenge_methods_supported": [
  "plain",
  "S256"
 ],
 "grant_types_supported": [
  "authorization_code",
  "refresh_token",
  "urn:ietf:params:oauth:grant-type:device_code",
  "urn:ietf:params:oauth:grant-type:jwt-bearer"
 ]
}

Тиймээс, id_token-ийг ашигласнаар та шаардлагатай бүх шинж тэмдгүүдийг жетоны ачаалалд шилжүүлэх боломжтой бөгөөд хэрэглэгчийн мэдээллийг хүсэх бүрт зөвшөөрлийн сервертэй холбогдож болохгүй. Энэ аргын сул тал нь серверээс хэрэглэгчийн өгөгдлийн өөрчлөлт шууд ирдэггүй, харин шинэ хандалтын тэмдэгтэй хамт ирдэг явдал юм.

Хэрэгжилтийн үр дүн

Тиймээс бид өөрсдийн OIDC серверийг нэвтрүүлж, түүнд холбогдох холболтыг програмын тал дээр тохируулсны дараа хэрэглэгчдийн мэдээллийг дамжуулах асуудлыг шийдсэн.
OIDC нь нээлттэй стандарт тул бидэнд одоо байгаа үйлчилгээ үзүүлэгч эсвэл серверийн хэрэгжилтийг сонгох сонголт бий. Бид Keycloak-ийг туршиж үзсэн бөгөөд энэ нь тохируулахад маш тохиромжтой байсан бөгөөд програмын тал дээр холболтын тохиргоог тохируулж, өөрчилсний дараа ашиглахад бэлэн боллоо. Хэрэглээний тал дээр холболтын тохиргоог өөрчлөх л үлдлээ.

Одоо байгаа шийдлүүдийн талаар ярьж байна

Байгууллагадаа анхны OIDC серверийн хувьд бид өөрсдийн хэрэгжүүлэлтийг угсарч, шаардлагатай бол нэмж оруулсан. Бусад бэлэн шийдлүүдийг нарийвчлан судалсны дараа үүнийг маргаантай зүйл гэж хэлж болно. Өөрсдийн серверийг хэрэгжүүлэх шийдвэр гаргахын тулд үйлчилгээ үзүүлэгчдийн зүгээс шаардлагатай функц байхгүй, түүнчлэн зарим үйлчилгээнд өөр өөр тусгай зөвшөөрөл олгосон хуучин систем байгаа эсэхээс болгоомжилж байсан. ажилчдын талаарх мэдээллийг аль хэдийн хадгалсан. Гэсэн хэдий ч бэлэн хэрэгжүүлэлтүүдэд нэгтгэх таатай нөхцөлүүд байдаг. Жишээлбэл, Keycloak нь өөрийн хэрэглэгчийн удирдлагын системтэй бөгөөд өгөгдөл нь түүнд шууд хадгалагддаг бөгөөд тэнд хэрэглэгчидээ гүйцэх нь тийм ч хэцүү биш юм. Үүнийг хийхийн тулд Keycloak нь шаардлагатай бүх шилжүүлгийн үйлдлийг бүрэн гүйцэтгэх боломжийг олгодог API-тай.

Баталгаажсан, сонирхолтой, миний бодлоор хэрэгжүүлэлтийн өөр нэг жишээ бол Ори Гидра юм. Энэ нь янз бүрийн бүрэлдэхүүн хэсгүүдээс бүрддэг тул сонирхолтой юм. Интеграцчлахын тулд та хэрэглэгчийн удирдлагын үйлчилгээг тэдний зөвшөөрлийн үйлчилгээтэй холбож, шаардлагатай бол өргөтгөх шаардлагатай.

Keycloak болон Ory Hydra нь зөвхөн бэлэн шийдэл биш юм. OpenID сангаас баталгаажуулсан хэрэгжилтийг сонгох нь хамгийн сайн арга юм. Эдгээр шийдлүүд нь ихэвчлэн OpenID гэрчилгээтэй байдаг.

OpenID Connect: дотоод програмуудыг захиалгаас стандарт руу шилжүүлэх

Хэрэв та OIDC серверээ хадгалахыг хүсэхгүй байгаа бол одоо байгаа төлбөртэй үйлчилгээ үзүүлэгчийн талаар бүү мартаарай. Өнөөдөр олон сайн сонголтууд байна.

Дараа нь юу юм

Ойрын хугацаанд дотоод үйлчилгээ рүү чиглэсэн урсгалыг арай өөрөөр хаах гэж байна. Бид OpenResty ашиглан тэнцвэржүүлэгч дээрх одоогийн SSO-г OAuth дээр суурилсан прокси руу шилжүүлэхээр төлөвлөж байна. Энд аль хэдийн олон бэлэн шийдлүүд байна, жишээлбэл:
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

Нэмэлт материал

jwt.io – JWT жетоныг баталгаажуулах сайн үйлчилгээ
openid.net/developers/certified - OIDC-ийн баталгаажуулсан хэрэгжилтийн жагсаалт

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх