Sunday, March 31, 2013

Mengenal OAM 11g Policy Model


Oracle Access Manager (OAM) 11gR1 merupakan solusi manajemen akses dari Oracle. OAM menyediakan fitur Single-Sign On (SSO) terhadap semua aplikasi yang berada di dalam perlindungan OAM. Pada umumnya ada 4 komponen utama pada arsitektur SSO OAM, yaitu access server, administration console, SSO agent, dan user identity store. Berikut ini adalah sedikit penjelasan dari masing-masing komponen tersebut:

  1. Access Server merupakan komponen yang bertanggung jawab dalam menyediakan layanan otentikasi dan otorisasi untuk SSO Agent. Ketika melakukan konfigurasi awal OAM, access server adalah WebLogic managed server pada domain IDMDomain yang bernama oam_server1
  2. Administration Console merupakan komponen yang mengatur dan menyimpan konfigurasi OAM policy model secara terpusat. Seusai melakukan konfigurasi awal OAM, administration console di-deploy pada WebLogic AdminServer dan dapat diakses melalui http://<AdminServerHost>:<AdminServerPort>/oamconsole
  3. SSO Agent merupakan komponen yang bertugas untuk melakukan penyaringan request HTTP dan meneruskannya ke access server untuk proses otentikasi dan otorisasi. SSO agent dapat berupa OAM 11g WebGate, OAM 10g WebGate, dan Oracle Single-Sign On (OSSO) Agent. Custom access client dapat dikembangkan menggunakan Access SDK ketika ada kebutuhan spesifik yang tidak dapat dilakukan SSO agent secara out-of-the-box.
  4. User Identity Store adalah LDAP store yang menyimpan seluruh identitas pengguna yang akan diotentikasikan oleh access server. User identity store pada OAM dapat bertipe Oracle WebLogic Embedded LDAP, Oracle Internet Directory (OID), Oracle Virtual Directory (OVD), Oracle Directory Server Enterprise Edition (iPlanet), Microsoft Active Directory (AD), dan Novell eDirectory.

Oracle menggambarkan OAM 11g policy model dengan diagram pada sebuah dokumentasi Oracle, yaitu Introduction to the OAM Policy Model. Diagram pada dokumen tersebut memperlihatkan tingkat teratas dari OAM 11g policy model ada pada komponen application domain. Application domain merupakan sebuah entitas yang berisi kumpulan resource-resource yang dilindungi OAM beserta skema otentikasi dan otorisasi yang berlaku terhadap resource tersebut. Pada OAM Administration Console, Application Domains berada di tabular Policy Configuration.
OAM Administration Console: Policy Configuration

Pada gambar tersebut, ada 4 application domain yang telah terdaftar di mana 2 di antaranya adalah application domain yang terdaftar secara default ketika selesai melakukan konfigurasi awal OAM 11g.  Kedua application domain tersebut adalah Fusion Apps Integration dan IAM Suite. Application domain Fusion Apps Integration digunakan untuk mengintegrasikan dengan Oracle Fusion Applications, sedangkan IAM Suite untuk mengintegrasikan dengan Oracle Identity and Access Management. Definisi dari application domain sangat relatif dari bagaimana seorang OAM administrator mengklasifikasikannya. Pengelompokkan dapat berdasarkan jenis aplikasi seperti BeehiveAgent yang merupakan kumpulan resource dari Beehive Server, atau berdasarkan grup aplikasi seperti Fusion Apps Integration dan IAM Suite.
OAM Administration Console: Application Domains

Gambar di atas menggambarkan 4 komponen dari application domain, yaitu Resources, Authentication Policies, Authorization Policies, dan Token Issuance Policies. Penjelasan dari keempat komponen tersebut adalah sebagai berikut:

  1. Resources merupakan daftar resource berupa URL pada sebuah application domain yang perlu dilindungi oleh OAM. Namun tidak semua resource perlu dilindungi, seperti misalnya resource gambar logo perusahaan. Menandai sebuah resource sebagai unprotected dapat mengurangi beban kerja OAM, karena Access Server tidak perlu lagi mengevaluasi resource tersebut terhadap policy yang ada.
  2. Authentication Policies merupakan daftar policy yang berisi mekanisme otentikasi yang berlaku pada sebuah application domain. Authentication policy mengikat satu atau lebih resource dengan authentication scheme, di mana authentication scheme ini terasosiasi dengan authentication module yang terhubung dengan User Identity Store.
  3. Authorization Policies merupakan daftar policy berisi aturan-aturan yang memberikan atau menolak hak akses pengguna terhadap resource yang ingin diakses. Batasan-batasan yang dapat didefinisikan antara lain seperti kisaran IP address dari client, pengguna atau grup pengguna tertentu, dan secara rentang hari dan jam tertentu.
  4. Token Issuance Policies merupakan daftar policy buries aturan yang digunakan ketika pertukaran token dilakukan untuk mempropagasikan identitas pengguna dengan menggunakan Oracle Security Token Services. 

Mari kita ambil salah satu resource HTTP yang berada pada application domain IAM Suite, yaitu /oamconsole. Gambar berikut dapat mendeskripsikan bahwa resource /oamconsole adalah resource bertipe HTTP pada application domain IAM Suite yang dilindungi oleh OAM dengan mekanisme otentikasi menggunakan OAM Admin Console Policy dan mekanisme otorisasi diatur menggunakan Protected Resource Policy.
Resource: /oamconsole

Gambar di bawah ini merupakan informasi yang lebih detil dari OAM Admin Console Policy,  di mana authentication policy tersebut menggunakan authentication scheme OAMAdminConsoleScheme.  Terlihat juga pada gambar tersebut policy ini juga mengikat resource lain yaitu /oamconsole/.../*, sehingga kedua resource tersebut menggunakan authentication scheme OAMAdminConsoleScheme.
Authentication Policy: OAM Admin Console Policy

Sebuah authentication scheme mendefinisikan challenge method, authentication level, dan authentication module yang dibutuhkan untuk mengotentikasi seorang pengguna. Challenge method adalah metode yang dibutuhkan untuk memperoleh informasi kredensial pengguna, seperti username dan password. Nilai authentication level merupakan bilangan bulat di mana semakin besar angkanya semakin tinggi tingkat kepercayaan proses otentikasinya. Authentication level memiliki arti jika seorang pengguna sudah terotentikasi oleh authentication scheme dengan authentication level 5, maka pengguna tersebut tidak perlu melakukan otentikasi kembali jika berhadapan dengan authentication scheme dengan authentication level lebih kecil sama dengan 5. Authentication module adalah unit terkecil dari proses otentikasi, salah satunya tipenya adalah modul otentikasi terhadap LDAP store. 
Authentication Scheme: OAMAdminConsoleScheme

Melihat lebih detil lagi dari OAMAdminConsoleScheme, authentication scheme tersebut menggunakan authentication module yang bernama LDAP sebagai authentication module-nya.
Authentication Module: LDAP

Gambar di atas memperlihatkan authentication module LDAP merujuk kepada user identity store yang bernama UserIdentityStore1.
User Identity Store: UserIdentityStore1

Pada gambar sebelumnya terlihat informasi detil dari user identity store UserIdentityStore1, yang merupakan koneksi user identity store terhadap LDAP store yang bertipe Oracle WebLogic Embedded LDAP yang mengacu kepada Embedded LDAP pada IDMDomain.
Authorization Policy: Protected Resource Policy

Authorization policy yang digunakan adalah Protected Resource Policy. Policy tersebut tidak memiliki batasan apapun, sehingga semua pengguna yang telah terotentikasi oleh authentication policy OAM Admin Console Policy dapat mengakses resource /oamconsole maupun /oamconsole/.../*.



Membuat Initiate Task pada Oracle BPM dengan BPM API

Pada Oracle BPM, setiap proses memiliki initiate task, yaitu task yang digunakan untuk melakukan inisialisasi pada proses tertentu.

Umumnya initiate task dilakukan melalui bpm workspace atau melalui web service atau melalui BPM API.

Berikut langkah-langkah untuk melakukan inisialisasi initiate task menggunakan BPM API
1. Buat object JAXB dari file XSD yang ada pada rancangan proses BPM.

2. Gunakan oracle.bpm.client.BPMServiceClientFactory untuk mendapatkan service instance BPM
public static BPMServiceClientFactory getServiceClientFactory(String username,
                                                                  String password,
                                                                  String url) {
        Map properties =
            new HashMap();

        properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.CLIENT_TYPE,
                       WorkflowServiceClientFactory.REMOTE_CLIENT);
        properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_PROVIDER_URL,
                       url);
        properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_INITIAL_CONTEXT_FACTORY,
                       "weblogic.jndi.WLInitialContextFactory");
        properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_SECURITY_PRINCIPAL,
                       username);
        properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_SECURITY_CREDENTIALS,
                       password);
        return BPMServiceClientFactory.getInstance(properties, null, null);
    }

3. Marshalling object JAXB ke dokumen XML (org.w3c.dom.Element)
public static Element marshallJaxbElementInitiateTask(Object obj) throws JAXBException,
                                                                 ParserConfigurationException,
                                                                 Exception {
        
        JAXBContext context = JAXBContext.newInstance(obj.getClass());
        Marshaller marshaller = context.createMarshaller();

        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        Document document = createDocument();
        
        Element payload = createPayloadElement(document);

        marshaller.marshal(obj, document);
        Element elt = document.getDocumentElement();
        
        payload.appendChild(elt);

        return payload;
    }

4. Lalu inisialisasi task dengan mengirim dokumen XML disertai ProjectName, ProcessName dan Version
public String initiateTask(String projectName, String processName, String version, Element payload) throws WorkflowException,
                                                           Exception {
        // Get the authentication context
        IBPMContext ctx = processUtils_.getBPMContext();
        
        // Check that current user is authorized to init the process
        String processDN =
            processUtils_.getInitableProcessDN(ctx, projectName, version,
                                               processName);
        if (processDN == null) {
            System.out.println("Process is not initable. Check deployment and privileges [user:" +
                               ctx.getUser() + "][process:" + projectName +
                               "/" + processName + "/" + version + "]");
            return null;
        }
        // InstanceManagmentService supports process instance services including initiating a process
        IInstanceManagementService instanceSvc =
            processUtils_.getBPMServiceClient().getInstanceManagementService();
        
        // Creates process and returns the task associated with the initiator human task in the process
        Task task = instanceSvc.createProcessInstanceTask(ctx, processDN);
        String taskId = task.getSystemAttributes().getTaskId();
        
        int taskNumber = task.getSystemAttributes().getTaskNumber();
        System.out.println("Initiator task [taskNumber:" + taskNumber + "][taskId:" + taskId + "]");
        
        // Returned task is "sparse", re-fetch to be able to update it with payload and outcome
        task = processUtils_.getHwfServiceClient().getTaskQueryService().getTaskDetailsById(ctx,
                                                                             taskId);
        // Set the payload on the task
        task.setPayloadAsElement(payload);
        
        // HWF TaskService is used to update task
        ITaskService taskSvc =
            processUtils_.getHwfServiceClient().getTaskService();
        
        // Update the task
        task = taskSvc.updateTask(ctx, task);
        
        // Update the outcome.  For initiator task the "SUBMIT" outcome is the default and completes the activity
        taskSvc.updateTaskOutcome(ctx, task,
                                  ProcessUtils.INIT_TASK_SUBMIT_OUTCOME);
        
        System.out.println("Process Instance Id : " +
                           task.getProcessInfo().getInstanceId());
        
        return task.getProcessInfo().getInstanceId();
    }

5. Berikut potongan code pada fungsi mainnya
public static void main(String[] args) {
        BPMServiceClientFactory cf =
            ProcessUtils.getServiceClientFactory("weblogic","welcome1","t3://localhost:7001");
        ProcessUtils processUtils = new ProcessUtils(cf);
        
        String projectName = "Leave";
        String processName = "LeaveProcess";
        String version = "1.0";

        TaskClient client = new TaskClient(processUtils);
        try {
            
            //create payload object
            CutiRequest inputType = new CutiRequest();
            inputType.setApprovalId(100);
            inputType.setDocs("fileLocatiom");
            inputType.setEmpID(100);
            inputType.setEmpNumber("empNumber");
            inputType.setFullName("fullName");
            inputType.setLocation("location");
            inputType.setRemark("renark");
            inputType.setTelNo("telNo");
            
            SubmitLeaveTaskPayloadType obj = new SubmitLeaveTaskPayloadType();
            obj.setCutiRequest(inputType);
            
            //create payload as jaxb element
            Element payload = ProcessUtils.marshallJaxbElementInitiateTask(obj);
            
            String processInstanceId = client.initiateTask(projectName, processName, version, payload);
            System.out.println(processInstanceId);
        } catch (WorkflowException e) {
            e.printStackTrace();
        } catch (JAXBException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Code ini terinspirasi dari java.net.

Semoga bermanfaat.  Cheers!!!

Friday, February 1, 2013

Tutorial Grails #5

Sebelumnya kita membahas tentang groovy, sekarang saatnya kita belajar grails. Langkah pertama yang harus kita lakukan adalah Instalasi.

Untuk memahami apa itu grails, mari kita mulai dengan grails architecture
Grails Architecture
Fondasi dari Grails  adalah Java Virtual Macine (JVM), dimana groovy dan java sebagai bahasa pemrogramannya. Grails Framework menggunakan :
  • GORM (Grails Object Relation Mapping), merupakan persistance yang didalamnya terdapat Hibernate Framework sebagai dasar.
  • SiteMash, adalah web framework yang digunakan rendering component seperti header, footer, navigation.
  • Spring Framework
  • Libraries

Sedangkan di Application Layer, terdapat Controller, Views dan Domain. Disini grails menggunakan konsep MVC, dimana Model diimplementasikan sebagai Domain. Untuk lebih jelasnya lihat gambar berikut ini :
Konsep MVC 


Sekarang saatnya beraksi dengan grails. Disini kita akan membuat web application sederhana, seperti ini :
Create
List / Read
Update and Delete

Proses pembuatannya saatlah mudah. Hanya memerlukan 4 langkah, yaitu :

  1. Create Application
  2. Create Domain
  3. Create Controller
  4. Run the application

Create Application

Tujuan: Membuat kerangka awal yang dibutuhkan oleh grails.

Create Domain

Edit file Form.groovy yang terletak di domain folder.
Tujuan: Membuat class model yang biasanya berhubungan dengan persistance dan controller.


Create Controller

Edit FormController.groovy yang terletak di controller folder.

Tujuan: Mengatur hubungan dengan View dan Domain.

Run the application

Jalankan http://localhost:8080/simple-app di browser.

Seperti kita lihat bersama, begitu mudahnya pembuatan CRUD dengan grails framework. Nantikan Tutorial Grails #6 dengan pembahasan View di grails.

Monday, January 28, 2013

Tutorial Grails #4

Seri tutorial Grails ini lanjutan dari sebelumnya, dimana pembahasan kita masih seputar groovy. Kali ini kita akan membahas tentang :
  • Groovy Unit Testing
  • XML di Groovy
  • Expandos

Groovy Unit Testing

Sama seperti java, groovy mempunyai unit testing. Dimana kita tidak perlu men-download terpisah dan sudah terintegrasi dengan JUnit. Mari kita lihat contoh penggunaannya unit testing di groovy:
class RangeTest extends GroovyTestCase {

 def lowerCaseRange = 'a'..'z'
 def upperCaseRange = 'A'..'Z'

 void testLowerCaseRange() {
  assert 26 == lowerCaseRange.size()
  assertTrue(lowerCaseRange.contains('b'))
  assertFalse(lowerCaseRange.contains('B'))
 }

 void testUpperCaseRange() {
  assert 26 == upperCaseRange.size()
  assertTrue(upperCaseRange.contains('B'))
  assertFalse(upperCaseRange.contains('b'))
  }

 void testAlphaRange() {
   def alphaRange = lowerCaseRange + upperCaseRange
   assert 52 == alphaRange.size()
   assert alphaRange.contains('b')
   assert alphaRange.contains('B')
   }
}
      

cara menajalankan tinggal ketikkan groovy RangeTest di command line. Groovy Unit Testing di extend dari class GroovyTestCase dan setiap method menggunakan naming convention testXXX sebagai prefix.

XML di Groovy

Extensible Markup Language, biasa digunakan untuk persist atau share data di enterprise applications.

Kenapa harus XML ?

Karena XML adalah text-based, sudah ada standart dan sudah banyak yang framework atau libraries yang mendukung XML di berbagai platform. Mari kita compare pembuatan XML dengan java (complicated) dengan groovy (simple and elegant).
package com.yukibuwana.testing;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class GenerateXML {

 /**
  * @param args
  * @throws ParserConfigurationException 
  * @throws TransformerException 
  */
 public static void main(String[] args) throws ParserConfigurationException, TransformerException {
  DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
  Document doc = builder.newDocument();
  
  Element todos = doc.createElement("todos");
  doc.appendChild(todos);
  
  Element task = doc.createElement("todo");
  task.setAttribute("id", "1");
  todos.appendChild(task);
  
  Element name = doc.createElement("name");
  name.setTextContent("Buy Beginning Groovy and Grails");
  task.appendChild(name);
  
  Element note = doc.createElement("note");
  note.setTextContent("Purchase book from Amazon.com for all co-workers.");
  task.appendChild(note);
  
  TransformerFactory tranFactory = TransformerFactory.newInstance();
  Transformer transformer = tranFactory.newTransformer();
  transformer.setOutputProperty(OutputKeys.INDENT, "yes");
  transformer.setOutputProperty(
    "{http://xml.apache.org/xslt}indent-amount", "2");
  
  Source src = new DOMSource(doc);
  Result dest = new StreamResult(System.out);
  transformer.transform(src, dest);
 }
}  

Mari kita lihat dengan groovy way

def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)
builder.setDoubleQuotes(true)
builder.todos {
    todo (id:"1") {
        name "Buy Beginning Groovy and Grails"
        note "Purchase book from Amazon.com for all co-workers."
    }
}

println writer.toString()      

Lalu hasil dari kedua seperti ini
Simple XML

Expandos

Expando adalah class di groovy.util yang digunakan untuk dynamically expandable bean. Artinya, kita bisa menambahkan properties atau closure di saat runtime. Untuk lebih mudahnya, mari kita lihat contoh berikut ini :
class User {
    String firstName;
    String lastName;
}

def user = new User(firstName: "Yuki", lastName: "Buwana")

println user.firstName + " " + user.lastName

Disini kita membuat class User dengan properties firstName dan lastName diawal. Sekarang kita lihat jika kita menggunakan Expando class
def user = new Expando()

user.firstName = "Yuki"
user.lastName = "Buwana"

println user.firstName + " " + user.lastName      

Yoooi... Kita bisa menambahkan properties pada saat runtime. It's amazing.

Banyak hal yang baru di groovy, seperti :

  • MOP
  • Generate Text with Template
Yang tidak kita bahas disini. Sebagai referensi groovy ada disini atau buku Groovy in Action. Disana dibahas lebih mendalam dan lebih detail.

Untuk tutorial selanjutnya, kita akan memulai dengan Grails itu sendiri.

Tuesday, January 22, 2013

Tutorial Grails #3

Tutorial ini lanjutan dari sebelumnya, dimana kita akan membahas tentang groovy lebih dalam. Disini kita akan membahas tentang :
  • Groovy Shell dan Groovy Console
  • Method dan closure
  • Collection di Groovy

Groovy Shell dan Groovy Console

Groovy Shell ataupun Groovy Console adalah interactive command line yang digunakan untuk menjalan perintah-perintah groovy. Mulai dari create, save ataupun load groovy script.
Groovy Shell
Cara menjalankan cukup ketikkan groovysh di command line.
Groovy Console
Cara menjalankan Groovy Console juga cukup mudah, sama seperti Groovy Shell. Cukup ketikkan groovyConsole. Untuk pemula disarankan menggunakan Groovy Console dibandingkan Groovy Shell.

Method dan Closure

Di java kita mengenal method sedangkan di groovy kita mengenal closure. Mari kita lihat perbedaannya :

Method in Java way
public String hello(String name) {
   return "Hello, " + name;
}
      

Method in Groovy way
def hello(name) {
   "Hello, ${name}"
}
      

Closure
def name = "Chris"
def printClosure = { println "Hello, ${name}" }

printClosure()

name = "Joseph"
printClosure()
      

Jadi perbedaannya method dengan closure adalah closure adalah object sedangkan method tidak.

Collection di Groovy

Collection berlaku juga di groovy, seperti :
  • List
  • Ranges
  • Sets
  • Arrays
  • Maps
Disini kita akan membahas Range Collection saja, karena range begitu mudah. Mari kita lihat contoh penggunaan range di groovy
def numRange = 0..9
println numRange.size()
numRange.each {print it}
println ""
println numRange.contains(5)

def alphaRange = 'a'..'z'
println alphaRange.size()
println alphaRange[1]

def reverseRange = 9..0
reverseRange.each {print it}


Sedangkan penggunaan range dalam pengulangan, seperti ini
println "Java style for loop"
for(int i=0;i<=9;i++) {
   println i
}

println "Groovy style for loop"
for (i in 0..9) {
   println i
}

println "Groovy range loop"
(0..9).each { i->
   println i
}
      

Jadi range adalah daftar uturan nilai. Range di implement dari java.lang.Comparable.

Banyak hal yang baru di groovy yang tidak bisa dituangkan disini. Next, kita akan membahas groovy lebih banyak lagi sebelum kita masuk ke grails.