Bowo Prasetyo Mengamankan Komponen Web dengan Realm Keamanan JDBC dan Otentikasi Berbasis Form
3 Desember 2011 http://www.scribd.com/prazjp http://www.slideshare.net/bowoprasetyo
Prasyarat
Java EE 6 SDK (http://java.sun.com/javaee/sdk/) Netbeans IDE v 7.0.1 (http://netbeans.org/) GlassFish Application Server v 3.1.1 (http://glassfish.java.net/)
Security Realm
Realm file
Credential pengguna di file lokal keyfile. Untuk koneksi non-HTTPS. Credential pengguna di database sertifikat. Untuk koneksi HTTPS. Credential administrator di admin-keyfile. Credential pengguna di database.
Realm sertifikat
Realm admin
Realm JDBC
Mekanisme Otentikasi
Username dan password di form default Form data otentikasi dapat dikustomisasi Otentikasi dasar dengan password terenkripsi Server mengotentikasi klien dengan public key Server dan klien saling mengotentikasi
Otentikasi digest
Otentikasi klien
Otentikasi mutualisme
Aplikasi Java EE
Mengamankan Komponen Web dengan Realm Keamanan JDBC dan Otentikasi Berbasis Form
Pada realm keamanan JDBC data otentikasi pengguna disimpan di database. Dilakukan dengan konfigurasi deployment descriptor dan konfigurasi GlassFish. Dan diperlukan koneksi ke database yang berisi: Tabel penyimpan username dan password. Tabel penyimpan group name.
Pada otentikasi berbasis form proses login sebagian ditangani oleh aplikasi. Dilakukan dengan konfigurasi deployment descriptor. Dan diperlukan tiga page baru:
login.jsp: menampilkan form login. logout.jsp: untuk logout dari sistem. error.jsp: menampilkan pesan kesalahan
login.
Class Diagram
Aplikasi terdiri atas 4 halaman JSP (index.jsp, login.jsp, logout.jsp, error.jsp), 1 database + security context dari web container.
index.jsp yang menampilkan Hello World! mempunyai 1 link ke logout.jsp dan
Security context me-redirect ke login.jsp yang berisi form login kalau pengguna belum login, atau ke error.jsp kalau pengguna gagal login, dan juga mengakses database.
Sequence Diagram
1. requestAccess: pengguna mengakses index.jsp. 2. checkAuthentication: security context mengecek pengguna sudah login atau belum. 3. 4.requestAuthenticationData: kalau belum login, security context me-redirect ke login.jsp untuk menampilkan form login. 5. supplyAuthenticationData: pengguna men-submit data login ke security context. 6. consultAuthenticationData: security context me-retrieve data otentikasi dari database. 7. setCredential: kalau data otentikasi valid, security context mengeset data credential pengguna di session, atau
Sequence Diagram
8. showError: kalau tidak valid, me-redirect ke error.jsp. Kembali ke no 3 selama data otentikasi belum valid.
9.setCredential: kalau sudah login, security context mengeset data credential ke index.jsp. 10.checkAuthorization: security context mengecek pengguna punya otorisasi mengakses url atau tidak. 11.buildHtml: kalau pengguna punya otorisasi, security context me-redirect ke index.jsp untuk menampilkan HTML, atau 12.showError: kalau tidak punya otorisasi, menampilkan pesan kesalahan.
Membuat database penyimpan data otentikasi di MySQL. Membuat JDBC Connection Pools di GlassFish. Membuat JDBC Resources di GlassFish. Menambah realm JDBC di GlassFish.
Database Otentikasi
create table usertable(username varchar(10) not null, password varchar(32) not null, primary key(username)); create table grouptable(username varchar(10) not null, groupname varchar(20) not null, primary key(username, groupname)); alter table grouptable add constraint FK_USERNAME foreign key(username) references usertable(username);
Jalankan server GlassFish Buka konsol adminstrator: http://localhost:4848/ Di pohon navigasi, buka node Resources JDBC JDBC Connection Pools New. Isi Pool Name: mis. SecurityPool. Pilih Resource Type: javax.sql.ConnectionPoolDataSource. Pilih Database Driver Vendor: mis. MySQL. Cek Ping: Enabled.
Klik Finish.
Pastikan bahwa JDBC driver database berada di dalam CLASSPATH. Untuk MySQL, download JDBC driver
mysql-connector-java-5.1.15-bin.jar dari
http://www.mysql.com/products/connector/
JDBC Resources
Jalankan server GlassFish Buka konsol adminstrator: http://localhost:4848/ Di pohon navigasi, buka node Resources JDBC JDBC Resources New. Isi JNDI Name: mis. jdbc/security. Pilih Pool Name: mis. SecurityPool. Isi Description: mis. Database for credential data. Klik OK.
JDBC Realm
Jalankan server GlassFish Buka konsol adminstrator: http://localhost:4848/ Di pohon navigasi, buka node Configurations server-config Security Realms. Klik New untuk membuat realm baru. Isi Name: mis. jdbc. Pilih Class name: ~.JDBCRealm. Isi properties seperti di halaman berikut. Klik OK.
JAAS Context: jdbcRealm JNDI: jdbc/security User Table: usertable User Name Column: username Password Column: password Group Table: grouptable Group Name Column: groupname Digest Algorithm: MD5 Encoding: Hex
Membuat direktori target (jdbc), jdbc/index.jsp, login.jsp, logout.jsp dan error.jsp. Menambah users ke tabel usertable: username=praz.jdbc. Menentukan mekanisme otentikasi: form-based. Menambah security roles: JdbcRole. Menambah security constraints: JdbcConstraint. Memetakan Role Users/Groups: JdbcRole praz.jdbc, FormRole praz.jdbc.
Menambah users ke tabel usertable: - username=praz.jdbc - password=praz2010 yang dienkripsi dengan fungsi MD5. Menambah groups ke tabel grouptable: - username=praz.jdbc - groupname=pengguna.
Jalankan Netbeans, buka modul web HelloEnterprise-war Klik kanan Web Pages New Folder... Beri nama jdbc direktori yang akan diamankan. Copy file index.jsp ke dalam direktori jdbc. Modifikasi isinya untuk menampilkan username yang sedang login.
<%@page contentType="text/html" pageEncoding="UTF8"%> <% String username = ((HttpServletRequest)pageContext.getRequest()).getUs erPrincipal().getName(); %> <!DOCTYPE html>
Jalankan Netbeans, buka modul web HelloEnterprise-war Buat login.jsp, logout.jsp dan error.jsp di luar direktori jdbc. Klik kanan Web Pages New JSP... Isi file name: login.jsp, klik Finish. Begitu juga untuk membuat logout.jsp dan error.jsp.
Halaman Logout
logout.jsp
Karena informasi login tersimpan di session, proses logout dapat dilakukan dengan cara mengakhiri session. Di JSP terdapat variabel session yang menyimpan obyek session. Untuk mengakhirinya digunakan metoda invalidate.
Halaman Logout
logout.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%> <% session.invalidate(); %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Halaman Logout</title> </head> <body> <h1>Anda telah logout!</h1> <a href="index.jsp">Kembali ke halaman depan</a> </body>
Halaman Error
error.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Halaman Kesalahan Login</title> </head> <body> <h1>Ada kesalahan login!</h1> <a href="index.jsp">Kembali ke halaman depan</a> </body> </html>
Jalankan Netbeans, buka modul web HelloEnterprise-war Di Projects Explorer, buka node Web Pages WEB-INF Buka file web.xml, klik tab Security Buka node Login Configuration, pilih Form Isi login page: /login.jsp, error page: /error.jsp, realm name: jdbc
<web-app> ... <login-config> <auth-method>FORM</auth-method> <realm-name>jdbc</realm-name> <form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/error.jsp</form-error-page> </form-login-config> </login-config> ...
Jalankan Netbeans, buka modul web HelloEnterprise-war Di Projects Explorer, buka node Web Pages WEB-INF Buka file web.xml Klik tab Security Buka node Security Roles, klik Add.. Isi Role Name dan Description
Klik OK
<web-app> ... <security-role> <description>Has access for JDBC security realm.</description> <role-name>JdbcRole</role-name> </security-role> ... </web-app>
Jalankan Netbeans, buka modul web HelloEnterprise-war Di Projects Explorer, buka node Web Pages WEB-INF Buka file web.xml Klik tab Security Di folder Security Constraints klik Add Security Constraints Isi Display Name
Di kolom Web Resource Collection klik Add.. Isi Resource Name, Description, dan URL Pattern(s)
Pilih HTTP Method(s), klik OK Cek Enable Authentication Constraint Isi Description dan Role Name(s): JdbcRole Cek Enable User Data Constraint Pilih Transport Guarantee: CONFIDENTIAL untuk meng-enkripsi username dan password dengan HTTPS.
<web-app> ... <security-constraint> <display-name>JdbcConstraint</display-name> <web-resource-collection> <web-resource-name>JdbcDirectory</webresource-name> <description>JDBC directory</description> <url-pattern>/jdbc/*</url-pattern> </web-resource-collection>
<description>Only JdbcRole is allowed to access.</description> <role-name>JdbcRole</role-name> </auth-constraint> <user-data-constraint> <description>Confidential user data</description> <transport-guarantee>CONFIDENTIAL</transportguarantee> </user-data-constraint>
... </web-app>
Jalankan Netbeans, buka modul web HelloEnterprise-war Di Projects Explorer, buka node Web Pages WEB-INF Buka file glassfish-web.xml, klik tab Security Buka node JdbcRole dan FormRole, klik Add Principal... Isi Principal Name: username pengguna GlassFish (mis. praz.jdbc) Klik OK
</glassfish-web-app>
Mendeploy HelloEnterprise
Di Project Explorer klik kanan project HelloEnterprise Deploy. Untuk membuka aplikasi, akses URL http://localhost:8080/HelloEnterprise-war/jdbc.
Skenario Pengujian
username: 'praz.basic' dan dipetakan hanya ke peran 'BasicRole' yang diberi akses hanya ke direktori /basic. username: 'praz.form' dan dipetakan hanya ke peran 'FormRole' yang diberi akses hanya ke direktori /form. username: 'praz.jdbc' dan dipetakan ke peran 'JdbcRole' yang diberi akses hanya ke direktori /jdbc, dan ke peran 'FormRole' yang diberi akses hanya ke direktori/form.
Skenario Pengujian
Ketiga pengguna harus dapat melakukan otentikasi. Username 'praz.basic' harus dapat mengakses direktori /basic tapi tidak dapat mengakses direktori /form dan /jdbc. Username 'praz.form' harus dapat mengakses direktori /form tapi tidak dapat mengakses direktori /basic dan /jdbc. Username 'praz.jdbc' harus dapat mengakses direktori /form dan /jdbc tapi tidak dapat mengakses direktori /basic. Username 'praz.unknown' yang tidak terdaftar harus gagal melakukan otentikasi.
Untuk skenario ini user praz.basic dan praz.form juga harus ditambah ke database. Menambah users ke tabel usertable: - username=praz.basic dan praz.form - password=praz2010 yang dienkripsi dengan fungsi MD5. Menambah groups ke tabel grouptable: - username=praz.basic dan praz.form - groupname=pengguna.
Referensi