Oracle WebLogic memiliki Embedded LDAP yang berfungsi sebagai penyedia otentikasi, otorisasi, credential mapping, dan role mapping. Ketika sebuah WebLogic Domain dibuat, secara default user dan group administratif seperti user weblogic tersimpan di WebLogic Embedded LDAP server. Secara fungsi, Embedded LDAP sudah menyediakan fungsi yang lengkap untuk WebLogic Domain. Namun pada ada kasus di mana menggunakan Embedded LDAP kurang disarankan, terutama pada deployment yang memiliki user lebih dari 10.000 user. Solusinya adalah dengan memindahkan LDAP service keluar dari WebLogic Domain.
Pada artikel kali ini saya ingin berbagi langkah-langkah untuk memigrasikan user yang tersimpan di WebLogic Embedded LDAP ke OpenLDAP. Pada dasarnya aktivitas migrasinya bisa dilihat pada diagram aktivitas berikut ini:
Activity Diagram for Embedded LDAP to OpenLDAP Migration |
Penjelasan detilnya adalah:
- Shutdown, Backup, and Startup WebLogic Domain
Langkah wajib setiap kali kita akan melakukan perubahan yang sifatnya domain-wide. Full backup dapat dilakukan dengan membuat tarball dari direktori di mana WebLogic Domain dan Oracle binary berada, diikuti dengan backup skema database-nya. Jika sudah selesai melakukan backup, jalankan kembali cukup AdminServer saja. - Export myrealm
Login ke Administration Console, pilih $NAMA_DOMAIN -> Security Realms -> myrealm -> Migration -> Export. Tulis nama direktori tempat hasil export akan disimpan, kemudian tekan tombol Save. Aktivitas ini akan menghasilkan beberapa file, namun yang perlu kita proses adalah file DefaultAuthenticator.dat yang sebenarnya merupakan file dengan format LDIF.Export DefaultAuthenticator - Parse DefaultAuthenticator.dat and Generate OpenLDAP LDIF
Pada tahap ini saya akan menggunakan Perl script sederhana yang memanfaatkan kekuatan regex untuk melakukan parsing file DefaultAuthenticator.dat dan mengubah formatnya menjadi OpenLDAP-friendly. Tidak semua field ter-cover pada script ini, namun cukup untuk kasus yang saya temui. Output dari script in akan menghasilkan beberapa file, namun yang penting adalah file people.ldif yang berisi seluruh user dan groups.ldif yang berisi seluruh group serta mapping-nya terhadap user yang ada.#!/usr/bin/perl -w # Author : Okky Hendriansyah (okky@nostratech.com) # Date : 2014/07/14 # Desc. : Oracle WebLogic Embedded LDAP LDIF Converter to OpenLDAP LDIF # Input : DefaultAuthenticator.dat exported from WebLogic Administration Console # Output : processed/excluded.ldif, processed/groups.ldif, processed/people.ldif, and processed/people_rdn.ldif # Run : ./weblogic_to_openldap.pl # Change this constant to resemble the directory root tree use constant ORGANIZATION => "dc=nostra,dc=tech"; # Open the exported DefaultAuthenticator LDIF file and slurp the whole contents open FILEHANDLE, '<DefaultAuthenticator.dat' or die $!; my $default_authenticator = do { local $/; <FILEHANDLE>; }; close FILEHANDLE; # Open output files open EXCLUDED_ENTRIES, '>processed/excluded.ldif' or die $!; open GROUP_ENTRIES, '>processed/groups.ldif' or die $!; open GROUP_RDN_ENTRIES, '>processed/groups_rdn.ldif' or die $!; open PERSON_ENTRIES, '>processed/people.ldif' or die $!; open PERSON_RDN_ENTRIES, '>processed/people_rdn.ldif' or die $!; # Split LDAP entries to array elements @ldap_entries = split /\n\n/, $default_authenticator; $total_ldap_entries = scalar @ldap_entries; # Variables initialization $total_groups = 0; $total_people = 0; $total_excluded = 0; my %groups; # Traverse all the LDAP entries foreach $ldap_entry (@ldap_entries) { # Initial parse group entries if ($ldap_entry =~ m/objectclass: groupOfUniqueNames/i) { # RDN if ($ldap_entry =~ m/dn: cn=([^,]+),ou=groups,ou=\@realm\@,dc=\@domain\@/i) { # Register the group $groups{$1} = qw(); } } # Parse person entries elsif ($ldap_entry =~ m/objectclass: inetOrgPerson/i) { # Person total $total_people++; # RDN if ($ldap_entry =~ m/dn: uid=([^,]+),ou=people,ou=\@realm\@/) { $person_uid_value = $1; $person_rdn = "dn: uid=$person_uid_value,ou=people," . ORGANIZATION . "\n"; $output = $person_rdn; # objectclass $person_objectclass = "objectClass: inetOrgPerson\n"; $person_objectclass .= "objectClass: organizationalPerson\n"; $person_objectclass .= "objectClass: person\n"; $person_objectclass .= "objectClass: top\n"; $output .= $person_objectclass; # Group while ($ldap_entry =~ m/wlsMemberOf: cn=([^,]+),ou=groups,ou=\@realm\@/gi) { push @{$groups{$1}}, $person_uid_value; } # description if ($ldap_entry =~ m/description: ([^\n]+)/i) { $person_description = "description: $1\n"; $output .= $person_description; } # cn if ($ldap_entry =~ m/cn: ([^\n]+)/i) { $person_cn = "cn: $1\n"; $output .= $person_cn; } # sn if ($ldap_entry =~ m/sn: ([^\n]+)/i) { $person_sn = "sn: $1\n"; $output .= $person_sn; } # uid if ($ldap_entry =~ m/uid: ([^\n]+)/i) { $person_uid = "uid: $1\n"; $output .= $person_uid; } # userpassword if ($ldap_entry =~ m/userpassword:: ([^\n]+)/i) { $person_userpassword = "userPassword:: $1\n"; $output .= $person_userpassword; } # mail if ($ldap_entry =~ m/mail: ([^\n]+)/i) { $person_mail = "mail: $1\n"; $output .= $person_mail; } # displayname if ($ldap_entry =~ m/displayname: ([^\n]+)/i) { $person_displayname = "displayName: $1\n"; $output .= $person_displayname; } # givenname if ($ldap_entry =~ m/givenname: ([^\n]+)/i) { $person_givenname = "givenName: $1\n"; $output .= $person_givenname; } # title if ($ldap_entry =~ m/title: ([^\n]+)/i) { $person_title = "title: $1\n"; $output .= $person_title; } # departmentnumber if ($ldap_entry =~ m/departmentnumber: ([^\n]+)/i) { $person_departmentnumber = "departmentNumber: $1\n"; $output .= $person_departmentnumber; } # employeenumber if ($ldap_entry =~ m/employeenumber: ([^\n]+)/i) { $person_employeenumber = "employeeNumber: $1\n"; $output .= $person_employeenumber; } # employeetype if ($ldap_entry =~ m/employeetype: ([^\n]+)/i) { $person_employeetype = "employeeType: $1\n"; $output .= $person_employeetype; } # o if ($ldap_entry =~ m/o: ([^\n]+)/i) { $person_o = "o: $1\n"; $output .= $person_o; } # preferredlanguage if ($ldap_entry =~ m/preferredlanguage: ([^\n]+)/i) { $person_preferredlanguage = "preferredLanguage: $1\n"; $output .= $person_preferredlanguage; } # telephonenumber if ($ldap_entry =~ m/telephonenumber: ([^\n]+)/i) { $person_telephonenumber = "telephoneNumber: $1\n"; $output .= $person_telephonenumber; } # jpegphoto if ($ldap_entry =~ m/jpegphoto:: ([^\n]+)/i) { $person_jpegphoto = "jpegPhoto:: $1\n"; $output .= $person_jpegphoto; } # Print to file print PERSON_ENTRIES "$output\n"; print PERSON_RDN_ENTRIES "uid=$person_uid_value,ou=people," . ORGANIZATION . "\n"; } } # No need to parse these entries else { $total_excluded++; print EXCLUDED_ENTRIES "$ldap_entry\n\n"; } } # Repeat traversing the LDAP entries but only group entries are processed foreach $ldap_entry (@ldap_entries) { # Compose group entries if ($ldap_entry =~ m/objectclass: groupOfUniqueNames/i) { # Group total $total_groups++; # RDN if ($ldap_entry =~ m/dn: cn=([^,]+),ou=groups,ou=\@realm\@,dc=\@domain\@/i) { $group_cn_value = $1; $group_rdn = "dn: cn=$group_cn_value,ou=groups," . ORGANIZATION . "\n"; $output = $group_rdn; # objectclass $group_objectclass = "objectClass: groupOfUniqueNames\n"; $group_objectclass .= "objectClass: top\n"; $output .= $group_objectclass; # cn if ($ldap_entry =~ m/cn: ([^\n]+)/i) { $group_cn = "cn: $1\n"; $output .= $group_cn; } # description if ($ldap_entry =~ m/description: ([^\n]+)/i) { $group_description = "description: $1\n"; $output .= $group_description; } # uniqueMember $group_uniquemember = ""; foreach $member_uid (@{$groups{$group_cn_value}}) { $group_uniquemember .= "uniqueMember: uid=$member_uid,ou=people," . ORGANIZATION . "\n"; } # handles groups without any member defined if ($group_uniquemember eq "") { $group_uniquemember .= "uniqueMember: \n"; } $output .= $group_uniquemember; # Print to file print GROUP_ENTRIES "$output\n"; print GROUP_RDN_ENTRIES "cn=$group_cn_value,ou=groups," . ORGANIZATION . "\n"; } } # Ignore if encounter the first entry of a person elsif ($ldap_entry =~ m/objectclass: inetOrgPerson/i) { # Skip all person entries last; } } # Close output files close EXCLUDED_ENTRIES; close GROUP_ENTRIES; close GROUP_RDN_ENTRIES; close PERSON_ENTRIES; close PERSON_RDN_ENTRIES; # Print summary print "Total Groups\t: $total_groups\n"; print "Total People\t: $total_people\n"; print "Total Excluded\t: $total_excluded\n"; print "Total Entries\t: $total_ldap_entries\n";
- Import People and Groups
Jalankan LDAP browser seperti Apache Directory Studio, koneksikan dengan OpenLDAP server yang sudah running. Import terlebih dahulu file people.ldif dilanjutkan oleh groups.ldif - Recreate Admin Users in OpenLDAP
Langkah ini opsional, kita juga dapat menggunakan user weblogic yang ter-import melalui langkah sebelumnya. - Reassociate Authentication Provider
Login kembali ke Administration Console. Pilih $NAMA_DOMAIN -> Security Realms -> myrealm -> Providers. Buat authentication provider baru dengan cara tekan tombol New dan masukkan tipe OpenLDAPAuthenticator. Pilih OpenLDAPAuthenticator tersebut dan ubah Control Flag menjadi SUFFICIENT. Setelah save, pilih tab Provider Specific dan masukkan detil informasi ke OpenLDAP server. Save setelah selesai memasukkan semua informasi tersebut. Kembali ke halaman Providers, masuk ke DefaultAuthenticator dan ganti Control Flag menjadi SUFFICIENT dan ubah urutan provider menjadi OpenLDAPAuthenticator, DefaultAuthenticator, dan DefaultIdentityAsserter. - Restart WebLogic Domain
Activate changes dan restart WebLogic Domain agar perubahan tersebut dapat diaplikasikan. - Remap Global Roles, especially Admin
Langkah ini tidak diperlukan jika kita tidak melakukan langkah ke-5. - Enable Identity Virtualization
Login ke WebLogic Enterprise Manager Fusion Middleware Control. Pilih $NAMA_DOMAIN -> WebLogic Domain -> Security -> Security Provider Configuration. Buka bagian Identity Store Provider kemudian pilih Configure. Tambahkan custom property virtualize dengan nilai true kemudian Save.Enable Identity Virtualization - Restart WebLogic Domain
Activate changes dan restart WebLogic Domain agar perubahan tersebut dapat diaplikasikan. - Reassociate Application-specific Roles/Group
Remap role dan grup pada masing-masing aplikasi, agar tidak lagi menggunakan grup yang ada di Embedded LDAP. - Test and Validate
Ganti password user yang tersimpan pada OpenLDAP dan lakukan aktivitas login dan logout baik ke Administration Console maupun ke aplikasi yang menggunakan WebLogic Authentication Provider. Seharusnya sekarang sudah bisa login menggunakan user dan password yang sesuai dengan OpenLDAP.
Selamat mencoba! :D
No comments:
Post a Comment