Artikel ini akan menjelaskan prosedur integrasi aplikasi dengan myITS SSO
Prerequisite
Aplikasi yang akan diintegrasikan harus sudah terdaftar pada myITS SSO. Anda bisa mendaftarkan aplikasi yang ingin diintegrasikan dengan menghubungi DPTSI-ITS untuk didaftarkan pada myITS SSO.
Setelah mendaftarkan aplikasi, DPTSI akan memberikan beberapa informasi terkait aplikasi sebagai berikut:
Client ID : unique ID aplikasi
Client Secret : key/password aplikasi
Scope : informasi user yang akan diterima oleh aplikasi setelah berhasil login
Base URI : URL yang diakses dari dashboard SSO
Redirect URI : URL yang diakses setelah melakukan login
Post Logout Redirect URI : URL yang diakses setelah melakukan logout
Informasi tersebut akan digunakan pada kodingan untuk integrasi
Requirements
PHP 5.4 or greater
phpseclib/phpseclib 2.0 or greater
CURL extension
JSON extension
Jika package phpseclib/phpseclib belum ada, akan auto diinstall saat menginstall package ini
Install
Berikut adalah tata cara menginstall package ini ke aplikasi Anda:
Install menggunakan composer
composer require myits/openid-connect-client:*
include class OpenIDConnectClient
use Its\Sso\OpenIDConnectClient; use Its\Sso\OpenIDConnectClientException;
Flow Authentication
Sebelum melakukan implementasi pada kode, perlu difahami bagaimana alur interaksi aplikasi client dengan myITS SSO. Berikut adalah flowchart autentikasi dari aplikasi ke myITS SSO:
function auth() adalah Redirect URI, flow ini berjalan hanya pada satu function. nama function boleh berbeda asalkan function tersebut diset sebagai Redirect URI
Integration
Berikut langkah-langkah untuk integrasi pada laravel setelah selesai instalasi
Buat function untuk login pada controller, dan definisikan variable
public function login() // nama boleh beda { try { // variable disimpan di config, di file config mengambil variable dari .env agar mudah disesuaikan // variable di bawah harus sama dengan apa yang diberikan oleh DPTSI, jika ada perubahan harap hubungi DPTSI lagi $provider = config('openid.provider'); // antara my.its.ac.id dan dev-my.its.ac.id $provider = config('openid.provider'); $clientId = config('openid.clientId'); $clientSecret = config('openid.clientSecret'); $redirectUri = config('openid.redirectUri'); $scope = config('openid.scope'); ...
Buat instance OIDC dan set beberapa attributes
... $oidc = new OpenIDConnectClient($provider, $clientId, $clientSecret); $oidc->setRedirectURL($redirectUri); $oidc->addScope($scope); // jika pada environment dev, maka set false pada host dan peer verify if(strtolower(config('app.env')) != 'production' && strtolower(config('app.env')) != 'prod') { $oidc->setVerifyHost(false); $oidc->setVerifyPeer(false); } ...
Panggil function utama
... $oidc->authenticate(); // Jika tidak ada login session user, akan redirect ke my.its.ac.id/signin // Jika sudah ada session user maka dilanjutkan mengeksekusi kode di bawahnya $userInfo = $oidc->requestUserInfo(); // ambil data user berdasarkan scope yang sudah ditentukan di awal $idToken = $oidc->getIdToken(); // ID token digunakan untuk logout session SSO ...
Ambil data yang diperlukan dari OIDC, dan lakukan sesuai kebutuhan aplikasi
... // Apabila aplikasi punya kemampuan untuk create dan update data user yang login $user = User::updateOrCreate([ 'id_user' => $userInfo->sub // sub adalah primary key dari user SSO dengan tipe UUID ], [ 'id_user' => $userInfo->sub, 'username' => $userInfo->preferred_username, 'primary_email' => $userInfo->email, 'alternate_email' => $userInfo->alternate_email, 'phone' => $userInfo->phone, 'picture' => $userInfo->picture, 'updater' => $userInfo->sub, ]); $user_session = array(); $user_roles = array(); foreach ($userInfo->group as $group) { if(in_array($group->group_name, self::USED_ROLE)) { $user_roles[] = [ 'id' => $group->group_id, 'name' => $group->group_name, ]; } } foreach ($userInfo->role as $role) { if(in_array($role->role_name, self::USED_ROLE)) { $user_roles[] = [ 'id' => $role->role_id, 'name' => $role->role_name, 'org_id' => $role->org_id, 'org_name' => $role->org_name, 'client_id' => $role->client_id, ]; } } $user_session['id_token'] = $idToken; $user_session['user_roles'] = $user_roles; $user_session['active_role'] = $user_roles[0]; // user session diset agar bisa dipakai untuk perluan authorization session([ 'auth' => $user_session, ]); ...
Login pada auth laravel
... // Jika kita sudah mendapatkan session OIDC/SSO, maka selanjutnya adalah // menghubungkan user yang login dengan SSO pada auth bawaan laravel Auth::login($user); // setelah itu redirect ke halaman default setelah login berhasil return redirect()->route('Dashboard::index'); } catch (OpenIDConnectClientException $e) { // Jika gagal login, hapus semua session, termasuk auth bawaan laravel Auth::logout(); Session::flush(); Session::save(); if ($e->getMessage() === self::OIDC_ERROR_STATE_UNDETERMINED) { return redirect('expired'); } return redirect('error'); }
Logout
public function logout() { try { // set variable yang dibutuhkan ... $oidc = new OpenIDConnectClient($provider, $clientId, $clientSecret); // set host dan peer verify ... $idToken = session('auth.id_token'); $oidc->signOut($accessToken, $redirect); return redirect()->route('Home::index'); // atau diredirect ke halaman login } catch (OpenIDConnectClientException $e) { // handle error ... } }
Notes
Pada laravel terdapat session login sendiri, jadi data user yang didapat dari OIDC harus dipass ke authentication bawaan laravel agar aplikasi bisa berjalan sesuai logic auth laravel.