OpenID Connect: otorisasi aplikasi internal dari kustom ke standar

Beberapa bulan yang lalu, saya menerapkan server OpenID Connect untuk mengelola akses ke ratusan aplikasi internal kami. Dari perkembangan kami sendiri, nyaman dalam skala yang lebih kecil, kami telah beralih ke standar yang diterima secara umum. Akses melalui layanan pusat sangat menyederhanakan operasi yang monoton, mengurangi biaya penerapan otorisasi, memungkinkan Anda menemukan banyak solusi yang sudah jadi dan tidak memutar otak saat mengembangkan yang baru. Pada artikel ini, saya akan berbicara tentang transisi ini dan gundukan yang berhasil kami isi.

OpenID Connect: otorisasi aplikasi internal dari kustom ke standar

Dahulu kala... Bagaimana semuanya dimulai

Beberapa tahun yang lalu, ketika terlalu banyak aplikasi internal untuk kontrol manual, kami membuat aplikasi untuk mengontrol akses di dalam perusahaan. Itu adalah aplikasi Rails sederhana yang terhubung ke database dengan informasi tentang karyawan, di mana akses ke berbagai fungsi telah dikonfigurasi. Pada saat yang sama, kami mengangkat SSO pertama, yang didasarkan pada verifikasi token dari sisi klien dan server otorisasi, token dikirim dalam bentuk terenkripsi dengan beberapa parameter dan diverifikasi di server otorisasi. Ini bukan pilihan yang paling nyaman, karena setiap aplikasi internal harus menggambarkan lapisan logika yang cukup besar, dan database karyawan sepenuhnya disinkronkan dengan server otorisasi.

Setelah beberapa waktu, kami memutuskan untuk menyederhanakan tugas otorisasi terpusat. SSO dipindahkan ke penyeimbang. Dengan bantuan OpenResty, sebuah templat ditambahkan ke Lua yang memeriksa token, mengetahui aplikasi mana yang akan dituju oleh permintaan, dan dapat memeriksa apakah ada akses di sana. Pendekatan ini sangat menyederhanakan tugas mengontrol akses ke aplikasi internal - dalam kode setiap aplikasi, tidak perlu lagi menjelaskan logika tambahan. Akibatnya, kami menutup lalu lintas secara eksternal, dan aplikasi itu sendiri tidak tahu apa-apa tentang otorisasi.

Namun, satu masalah tetap belum terselesaikan. Bagaimana dengan aplikasi yang membutuhkan informasi tentang karyawan? Dimungkinkan untuk menulis API untuk layanan otorisasi, tetapi kemudian Anda harus menambahkan logika tambahan untuk setiap aplikasi tersebut. Selain itu, kami ingin menghilangkan ketergantungan pada salah satu aplikasi yang kami tulis sendiri, berorientasi pada masa depan untuk diterjemahkan ke dalam OpenSource, pada server otorisasi internal kami. Kita akan membicarakannya lain waktu. Solusi untuk kedua masalah tersebut adalah OAuth.

dengan standar umum

OAuth adalah standar otorisasi yang dapat dipahami dan diterima secara umum, tetapi karena fungsinya saja tidak cukup, mereka segera mulai mempertimbangkan OpenID Connect (OIDC). OIDC sendiri merupakan implementasi ketiga dari standar autentikasi terbuka, yang mengalir ke add-on melalui protokol OAuth 2.0 (protokol otorisasi terbuka). Solusi ini menutup masalah kurangnya data tentang pengguna akhir, dan juga memungkinkan untuk mengubah penyedia otorisasi.

Namun, kami tidak memilih penyedia tertentu dan memutuskan untuk menambahkan integrasi dengan OIDC untuk server otorisasi kami yang sudah ada. Yang mendukung keputusan ini adalah fakta bahwa OIDC sangat fleksibel dalam hal otorisasi pengguna akhir. Dengan demikian, dukungan OIDC dapat diterapkan di server otorisasi Anda saat ini.

OpenID Connect: otorisasi aplikasi internal dari kustom ke standar

Cara kami mengimplementasikan server OIDC kami sendiri

1) Membawa data ke bentuk yang diinginkan

Untuk mengintegrasikan OIDC, perlu membawa data pengguna saat ini ke dalam bentuk yang dapat dimengerti oleh standar. Di OIDC ini disebut Klaim. Klaim pada dasarnya adalah bidang final dalam basis data pengguna (nama, email, telepon, dll.). Ada daftar standar perangko, dan semua yang tidak termasuk dalam daftar ini dianggap sebagai kebiasaan. Oleh karena itu, poin pertama yang perlu Anda perhatikan jika Anda ingin memilih penyedia OIDC yang sudah ada adalah kemungkinan kustomisasi merek baru yang nyaman.

Kelompok keunggulan digabungkan menjadi subset berikut - Lingkup. Selama otorisasi, akses diminta bukan untuk merek tertentu, tetapi untuk cakupan, meskipun beberapa merek dari cakupan tidak diperlukan.

2) Melaksanakan hibah yang diperlukan

Bagian selanjutnya dari integrasi OIDC adalah pemilihan dan penerapan jenis otorisasi, yang disebut hibah. Skenario interaksi lebih lanjut antara aplikasi yang dipilih dan server otorisasi akan bergantung pada hibah yang dipilih. Skema teladan untuk memilih hibah yang tepat ditunjukkan pada gambar di bawah ini.

OpenID Connect: otorisasi aplikasi internal dari kustom ke standar

Untuk aplikasi pertama kami, kami menggunakan hibah yang paling umum, Kode Otorisasi. Perbedaannya dari yang lain adalah bahwa ini adalah tiga langkah, yaitu. sedang menjalani pengujian tambahan. Pertama, pengguna mengajukan permintaan izin otorisasi, menerima token - Kode Otorisasi, kemudian dengan token ini, seolah-olah dengan tiket perjalanan, meminta token akses. Semua interaksi utama skrip otorisasi ini didasarkan pada pengalihan antara aplikasi dan server otorisasi. Anda dapat membaca lebih lanjut tentang hibah ini di sini.

OAuth menganut konsep bahwa token akses yang diperoleh setelah otorisasi harus bersifat sementara dan sebaiknya diubah rata-rata setiap 10 menit. Pemberian Kode Otorisasi adalah verifikasi tiga langkah melalui pengalihan, setiap 10 menit untuk mengubah langkah seperti itu, sejujurnya, bukanlah tugas yang paling menyenangkan bagi mata. Untuk mengatasi masalah ini, ada hibah lain - Refresh Token, yang juga kami gunakan di negara kami. Semuanya lebih mudah di sini. Selama verifikasi dari hibah lain, selain token akses utama, yang lain dikeluarkan - Token Penyegaran, yang hanya dapat digunakan sekali dan masa pakainya biasanya lebih lama. Dengan Refresh Token ini, ketika TTL (Time to Live) dari token akses utama berakhir, permintaan token akses baru akan sampai ke titik akhir hibah lain. Refresh Token yang digunakan segera direset ke nol. Pemeriksaan ini dua langkah dan dapat dilakukan di latar belakang, tanpa disadari oleh pengguna.

3) Siapkan format keluaran data khusus

Setelah hibah yang dipilih diterapkan, otorisasi berfungsi, perlu disebutkan mendapatkan data tentang pengguna akhir. OIDC memiliki titik akhir terpisah untuk ini, di mana Anda dapat meminta data pengguna dengan token akses Anda saat ini dan jika sudah diperbarui. Dan jika data pengguna tidak terlalu sering berubah, dan Anda perlu mengikuti data saat ini berkali-kali, Anda dapat mengambil solusi seperti token JWT. Token ini juga didukung oleh standar. Token JWT itu sendiri terdiri dari tiga bagian: header (informasi tentang token), muatan (data apa pun yang diperlukan) dan tanda tangan (tanda tangan, token ditandatangani oleh server dan nanti Anda dapat memeriksa sumber tanda tangannya).

Dalam implementasi OIDC, token JWT disebut id_token. Itu dapat diminta bersama dengan token akses normal dan yang tersisa hanyalah memverifikasi tanda tangan. Server otorisasi memiliki titik akhir terpisah untuk ini dengan banyak kunci publik dalam formatnya JWK. Dan berbicara tentang ini, perlu disebutkan bahwa ada titik akhir lain, yang didasarkan pada standar RFC5785 mencerminkan konfigurasi server OIDC saat ini. Ini berisi semua alamat titik akhir (termasuk alamat cincin kunci publik yang digunakan untuk penandatanganan), merek dan cakupan yang didukung, algoritme enkripsi yang digunakan, hibah yang didukung, dll.

Misalnya di 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"
 ]
}

Jadi, dengan menggunakan id_token, Anda dapat mentransfer semua keunggulan yang diperlukan ke payload token dan tidak menghubungi server otorisasi setiap kali meminta data pengguna. Kerugian dari pendekatan ini adalah bahwa perubahan data pengguna dari server tidak langsung datang, tetapi bersamaan dengan token akses baru.

Hasil implementasi

Jadi, setelah mengimplementasikan server OIDC kami sendiri dan mengonfigurasi koneksi ke sana di sisi aplikasi, kami memecahkan masalah transfer informasi tentang pengguna.
Karena OIDC adalah standar terbuka, kami memiliki opsi untuk memilih penyedia atau implementasi server yang ada. Kami mencoba Keycloak, yang ternyata sangat nyaman untuk dikonfigurasi, setelah mengatur dan mengubah konfigurasi koneksi di sisi aplikasi, siap digunakan. Di sisi aplikasi, yang tersisa hanyalah mengubah konfigurasi koneksi.

Berbicara tentang solusi yang ada

Di dalam organisasi kami, sebagai server OIDC pertama, kami menyusun implementasi kami sendiri, yang dilengkapi seperlunya. Setelah tinjauan mendetail tentang solusi siap pakai lainnya, kami dapat mengatakan bahwa ini adalah poin yang bisa diperdebatkan. Mendukung keputusan untuk mengimplementasikan server mereka sendiri, ada kekhawatiran dari pihak penyedia karena tidak adanya fungsionalitas yang diperlukan, serta adanya sistem lama di mana terdapat otorisasi khusus yang berbeda untuk beberapa layanan dan cukup banyak data tentang karyawan sudah disimpan. Namun, dalam implementasi yang sudah jadi, ada kemudahan untuk integrasi. Misalnya, Keycloak memiliki sistem manajemen penggunanya sendiri dan data disimpan langsung di dalamnya, dan tidak akan sulit untuk menyalip pengguna Anda di sana. Untuk melakukan ini, Keycloak memiliki API yang memungkinkan Anda untuk sepenuhnya melakukan semua tindakan transfer yang diperlukan.

Contoh lain dari penerapan bersertifikat, menarik, menurut saya, adalah Ory Hydra. Ini menarik karena terdiri dari berbagai komponen. Untuk mengintegrasikan, Anda perlu menautkan layanan pengelolaan pengguna Anda ke layanan otorisasi mereka dan memperluasnya sesuai kebutuhan.

Keycloak dan Ory Hydra bukan satu-satunya solusi yang tersedia. Yang terbaik adalah memilih implementasi yang disertifikasi oleh OpenID Foundation. Solusi ini biasanya memiliki lencana Sertifikasi OpenID.

OpenID Connect: otorisasi aplikasi internal dari kustom ke standar

Juga jangan lupakan penyedia berbayar yang ada jika Anda tidak ingin mempertahankan server OIDC Anda. Saat ini ada banyak pilihan bagus.

Apa Selanjutnya

Dalam waktu dekat, kami akan menutup lalu lintas ke layanan internal dengan cara yang berbeda. Kami berencana untuk mentransfer SSO kami saat ini pada penyeimbang menggunakan OpenResty ke proxy berdasarkan OAuth. Sudah banyak solusi siap pakai disini, misalnya:
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

Bahan tambahan

jwt.io – layanan yang baik untuk memvalidasi token JWT
openid.net/developers/certified - daftar implementasi OIDC bersertifikat

Sumber: www.habr.com

Tambah komentar