Saturday, December 25, 2010

API Management and Security

Many companies are creating an API and they like to have a developer community.

Apart from the API Design & Development there is another important activity
API Management. As of this Writing the Three major companies in the API Management are

1. Mashery
2. apiGee
3. SONOA

Almost the business model of all the above mentioned companies are very similar.
like providing the below API Management Capabilities

Throttling, alerts , Usage graphs,API key provisioning and Management ,a dedicated portal to host the documentation,blogs,forums etc..

There is no doubt these are very essential features for a corporate to support their API's and developers.

SO does all the companies who have an API are dependent on a separate vendor for API Management?

Let's forget about the cost involved for having a dedicated Managment Vendor. Apart from the Cost there is also a significant impact on the security

API's which deals with Payments/credit card information/restricted Data(restriction levels are classified by the company which exposes an API). are not considering a dedicated vendor for API Management

eg: Paypal,Master card Payment Gateway,Amazon s3,e bay

As long as the Data produced and Consumed by the API are not required to be very secure this API Management Model seems to be very good.

eg: Bestbuy API which exposes the catlogs,products etc..Netflix,NYTimes are exposing their API through a separate API management vendor.

Not To say that Security is compromised when we have an API Management vendor outside the Network.

But it does have an impact on the security Design of the API being Exposed through the API Management Vendor.

eg: https (point to point connection are not enough to secure when you have a management proxy.So security has to be end to end.)

XML Encryption is an option to Provide the End to end Security.

Engaging an API Management vendor outside the corporate network should also depend on the 'Security of the Data flowing through the API'.

While Architecting a solution for this model surely Architect will have to take a critical decision by listing the tradeoffs .

Please let me know if i am not correct in my Views.

Thanks
Prem

Thursday, October 14, 2010

Deep Dive into Asymmetric Encryptrion

I came across an issue while encrypting a xml using Apache XML Securty.

Error Occured when the code Reached the below line.

//cipher.doFinal(ContainerDoc,PayloadDoc.getRootElement());

When i digged in to that issue a lot of things got cleared in a much better way .

I am not going to write all basics of Asymmetric Encryption.I did an Asymmetric Encryption as two Step Process as Described by many Articles on Web.

a. Generated a AES128 Symmetric key and encrypted the Data
b. Encrypted the Symmetric key with a Public Key.

I was aware of only one Reason for the above Steps. As the Asymmetric Encryption is Expensive the symmetric and Asymmetric Technique described above will Increase the Performance and will make the System More scalable.

But that's not the Only One Reason.

Another Very Important Reason. The x.509V3 Certificates which has RSA 1024 bits key, cannot Encrypt more than 117 bytes.

So,Use an Asymmetric key to split the data into blocks and encrypt it(this could be done on data of any size)

How this 117 bytes is calculated is given in the below link?

http://www.owasp.org/index.php/Digital_Signature_Implementation_in_Java

Saturday, September 25, 2010

Error Handling REST ful WebServices

Looks to be a Easy One but Really Not.

Like Anyone before doing something i read many documents and referrred many REST webserivces api in the market by leading companies.

And there is no common practice.It purely depends on the Architect/Designer of the System.

for eg: Ebay returns a status code HTTP 200 OK in case of request error(eg :request element is not formatted as expected) and then a Custom Error Code. which is not so correct in my View.

Anything which is 200 OK is considered as SUCCESS as per HTTP Spec, and for application which are created with HTTP Awareness. the above apporoach may defeat that. Still i understand there should be a strong reason why ebay did that ...

OK coming back to Error Handling..

a. Create a error schema or object ( with complex type customcode, error classification,Message) you can keep it simple like this or you can even return the error param.

b. inside the catch block set the appropriate values for that error conditions.

c. Set the HTTP Status to appropriate status, if the Error Classification is Request ERROR.(i use http 400 for this)

How to Classify ?

Any Problem in the Request Data can be considered as REQUEST ERROR

if valid Request data, Any Problem while processing the Request is a APPLICATION ERROR. (this error includes business rule violations)


if Required Have another classification for SYSTEM ERROR

A Very important Rule is Never /Ever Let your application to expose a stack trace to client. Your application should handle and all the Errors and Exceptions and return specific code/Generic code . Make Sure you Log the Details on the Server.


Please let me know if you have any questions.

Thanks
Premkumar.

RestEasy - Not Easy for Validation

After a Long time i am back to my Blog to post my findings on REST easy and Rest ful web services implementation practices.

Though my Preference is' Jersey ' i was in a position to select Resteasy for the implementation

The documentation explains about Decorators for Validation. it applies only for Marhsalling. for unmarshaling there are no decorators available in the framework.
Writing a New Decorator for unmarshaling is not an easy task.

So i used a Validator class from javax.xml.bind.* which worked perfectly.

But the Trick Here is you cannot Validate and let the framework bind on the same input Stream .so you need to clone the input stream ,one for validation and the other one for binding. (this binding will be done by Rest easy framework)

This worked really well.

Code to clone Input Stream

org.apache.commons.io.IOUtils;

private List cloneInputStream(InputStream iStream) {
List inArray = null;
List errorList = new ArrayList();
try {

if (iStream != null) {
String base = org.apache.commons.io.IOUtils.toString(iStream);
logger.debug("called cloneInputStream: input stream content -> {}",
base);
inArray = new ArrayList();
for (int i = 0;
i < APIConstants.INPUTSTREAM_CLONES; i++) {
inArray.add(IOUtils.toInputStream(base));
}
}
return inArray;
}
Please let me know if you have any questions.

Thanks
Premkumar

Saturday, June 19, 2010

REST / JAMON Integration

I liked to Monitor all the Calls to Made to My REST ful webservices.

JAMON is Considered to Be a better Monitoring Tool i liked it very much. It is easy to integrate easy to monitor .I downloaded it from

http://sourceforge.net/projects/jamonapi/files/

Jamon.jar (Required)
Jamon.war (optional)

But i suggest to integrate this to the web app. It has a nice admin screen to view the calls made to the services.

a. Added jamon.jar to the Project and added the monitors to My REST Services.

//Code
mon = MonitorFactory.start("EmpDetailsMonitor");

//My Business Logic

mon.stop();

b. I modified my application.xml to include the jamon.war file.

c. Built the .ear file again Redeployed it.

Call the Webservice in which you added the EmpDetails Monitor

Navigate to the admin screen .you should be able to access like below

http://hostname:port/jamon/jamonadmin.jsp

You should see the monitor Which you added with all other Call Specific Metrics

-Prem

Saturday, March 13, 2010

Oracle PDK Portlet/ FLEX (Request Parameter from a Portlet to swf file)

I had an Requirement to pass my OID userName to a PDK/Flex Portlet. (I have my employee ID as the OID userName) and as always i want that to default in the userName Field of My shockWave File (.swf)

Environemnt: Flex 3.2/ oracle Portal 10.1.4

Steps.

1. Create you Flex app .have a shock wave file ready.

2.Make Sure you have the below Code to Access your request Parameter

empName = Application.application.parameters.empName;

3. upload the files(history.css,AC_OETags.js,history.js) to a portal page group.you can User Oracle Drive , any WebDav Client or just upload manually.

for eg:

/portal/page/portal/ABCIntranet/js/AC_OETags.js
/portal/page/portal/MCSIntranet/css/history.css
/portal/page/portal/MCSIntranet/js/history.js

3.Create a Portlet using the Standard Wizard. on the Show Mode Jsp. Paste the below Code


<%
String empName = null;
empName = request.getHeader("x-oracle-cache-user") ;
%>


4. in the div tag where you embed the flash file make sure you are passing the FlashVars Parameter with the String Value(in this case i used empName).


eg:



embed src="/portal/page/portal/ABCIntranet/swf/Flash1.swf" quality="high" bgcolor="#ffffff" FlashVars ='empName=<%=empName%>'



4.Register,Publish your Portlet.

Thanks
Prem

Friday, March 12, 2010

Android/Oracle BPEL

I was able to build a Android app which calls a Oracle BPEL Webservice and process the response sent back from the Service.

This is what i did.

created a Simple BPEL Process and Deployed to BPM 10.1.3.4

Created an Android App on the Eclipse(Android SDK) named it as BPELAndroid.

Added the ksoap2 jar file downloaded from

http://code.google.com/p/ksoap2-android

Note:
When i Called the service from a Blackberry i used a ksoap jar file ksoap2-j2me-core-prev-2.1.2.jar. This JAR file has a HTTPTransport class

This HTTPTransport class will not work for Android.


Wrote the Code below.

package com.prem.android;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.app.Activity;
import android.os.Bundle;

public class BPELAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SoapObject userLoginReposne = null;

try{
HttpTransportSE ht = new HttpTransportSE(
"wsdl url");

/*Please make sure you have VER11 to invoke the BPEL Webservice

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);

SoapObject request = new SoapObject(
"http://xmlns.mascocs.com/TheLoop/request",
"name of soap object");

request.addProperty("employeeName","1021633");

request.addProperty("pword","Masco123");

request.addProperty("token","");

envelope.setOutputSoapObject(request);


ht.call("opertatioName",envelope);

userLoginReposne = (SoapObject) envelope.bodyIn;

System.out.println("the request 1 is"
+ userLoginReposne.toString());

setContentView(R.layout.main);

}catch(Exception e){
System.out.println("the Exception is"+e.toString());
}

}
}

Tuesday, February 23, 2010

Flex3 and Rest Webservices.

In our organization since we want leverage Oracle Bpel , i used Flex with Oracle Bpel Webserivces for creating Dashboards and other Rich Internet applications.

Recently i was developing REST webserivces for another project. it was very interesting...As we all know in flex3 we can only use the HTTP service for invoking a REST webservice.


The main reasons why i selected REST instead of BPEL to bind/post data on a flex page is

did not require an ws-security extensions..

did not require soap-header information..

am not willing to select an open source implementation for that project...


Tools required: Ganymede 3.4 and myclispse 7.5 installation (make sure it supports jsr311 implementation).

Framework: Jersey.

use case:

submit a form with firstname and last name and persist in a database

Step 1.


Create a POJO class ,annotate with @XmlRootElement


import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Employee{

private String firstName;
private String lastName;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}


public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

}

Step 2.

Create a Resource class



package com.prem.restservices;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.ArrayList;
import java.util.List;


import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import com.sun.jersey.spi.resource.Singleton;

@Produces("application/xml")
@Path("empdetails")
@Singleton
public class CustomersResource {


String jdbcURL = "jdbc:oracle:thin:@hostname:port:SID";
String user = "username";
String passwd = "password";


public Connection getConnection() throws SQLException{

Connection conn;
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
conn = DriverManager.getConnection(jdbcURL, user, passwd);
return conn;

}

public CustomersResource() {
}



@POST
@Path("add")
@Produces("text/plain")
@Consumes("application/xml")
public String addEmployee(Employee employee) {

Connection conn = null;
PreparedStatement pstmt = null;

try {


conn = getConnection();

//Insert Data in your Database

} catch (java.sql.SQLException e) {
// TODO Auto-generated catch block
System.out.println("Exception in ad Employee" +customer.toString());
}finally{
try{
//Release Resources

}catch(Exception e){
//log in exception
}
}

return "employee " + employee.getFirstName() + " added";
}



Flex Code

mx:Script
![CDATA[
private function send_data():void {
userRequest.send();
}
]]

mx:Form x="22" y="10" width="493"
mx:HBox
mx:Label text="FirstName"
mx:TextInput id="firstname"
mx:HBox
mx:HBox
mx:Label text="LastName"
mx:TextInput id="lastname"
mx:HBox
mx:Button label="Submit" click="send_data()"
mx:Form



mx:HTTPService id="userRequest" url="Webservice URL" contentType="application/xml" showBusyCursor="true" useProxy="false"
mx:request xmlns=""
employee
firstName{firstname.text}firstName
lastName{lastname.text}lastName
employee
mx:request
mx:HTTPService

Saturday, February 13, 2010

Android/ JDBC

Hi,

This week i was able to develop an Android App to get data from an Oracle Database.

Here is my Code .


package com.prem.JDBCAndroid;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import android.app.Activity;
import android.database.SQLException;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import android.util.Log;

public class JDBCAndroid extends Activity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

try {
String userName = getDataFromOraDB();
TextView tv = new TextView(this);
tv.setText(userName);
setContentView(tv);
} catch (SQLException e) {
Toast.makeText(this, e.getMessage(), 1).show();
} catch (ClassNotFoundException e) {
Toast.makeText(this, e.getMessage(), 1).show();
}

}

public String getDataFromOraDB() throws SQLException,
ClassNotFoundException {

String name = null;
String jdbcURL = "jdbc:oracle:thin:@hostname:portname:sid";
String user = "uname";
String passwd = "pwd";
// Load the Oracle JDBC driver

try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn;
ResultSet rs;
Statement stmt;
conn = DriverManager.getConnection(jdbcURL, user, passwd);
stmt = conn.createStatement();
rs = stmt.executeQuery("select USERNAME from SomeTableName");
if (rs.next()) {
name = rs.getString("USERNAME");
}
} catch (java.sql.SQLException e) {
// TODO Auto-generated catch block
System.out.println("the exception is" + e.toString());
}

Toast.makeText(getApplicationContext(), name, 1).show();
return name;
}

}





If you still have issues please check your AndroidManifest.xml file if it has the

below line

uses-permission android:name="android.permission.INTERNET"

TimeZone in Workbrain5.0.21

ETM_CLOCK_FACTOR_TIME_ZONE


Description: This parameter determines how an employee’s time zone is determined. When set to client_browser, the time zone is set by the user’s PC, although the actual date and time from the PC is not used.

When set to employee_udf, employee time zones are determined from stored values in the TIMEZONE table. If the employee does not have EMPLOYEE.TZ_ID set, then server time is used.

When set to False, all time zones are the same as the server.



Valid Values: client_browser, employee_udf, False

Default Value: False

Location: system/WORKBRAIN_PARAMETERS/

-Prem

Time out in Workbrain5.0.2.1

a.Application SessionTimeOut

This happens through registry setting

Select * from workbrain_registry where wbreg_name='timeout'



b. PageSession TimeOut


Application gives an option to the user to set their timeout on
specific pages (only sys admins can configure this.)


select * from workbrain_page gives the list of pages which are configured for a page level time out.

I changed this as we do not want this to be same as App time out for some business reasons.

A page session Time out takes Priority if it is less than Application TimeOut

-Prem

SQl Server Datasource Configuration/ORacle ESB

The below metalink note helps to configure a sql server datasource .

after which we can create a Database adapater

How To Setup Database Adapter Interfaces Using a Microsoft SQL (MSSQL) Server 2000 Database [ID 737497.1]


I was able to move the legacy data to an oracle ERP database through routing service of Oracle ESB


Thanks
Prem

Wednesday, January 27, 2010

InBound Security in BPEL

Hello All,

A simple way to protect a BPEL Process.

1. Navigate to the /$ORACLE_HOME/bpel/domains/Domain_name/config/message-handlers.xml

2. Configure the process name which needs to be protected in the 'SecuredProcesses' tag

3.



property id="SecuredProcesses"



inbound-flow
message-handler id="Domain"
message-handler id="security"
inbound-flow






4. Generate a encrypted password based on DES algorithm.(i did through a java class)

[CDATA[TOEXz08rReMqnYt1uPZFjw==]]

10.1.3.3.1 works only with a DES algortihm .

Make sure the password is a properly encrypted if you miss one character you will

get a cipher error while deploying.

5. paste the below two lines in your bpel.xml file

configurations
property name="user" encryption="plaintext" oc4jadminproperty
property name="pw" encryption="encrypted" CDATA[TOEXz08rReMqnYt1uPZFjw==]]"property
configurations

make sure the you dont miss tags in the above encryption.

6. Deploy the process

7. used Soap UI for testing. Please make sure you pass the username /password in the token through soap header


Thanks
Prem.

Sunday, January 17, 2010

JPA Databinding in JSF Page

Hello All,

The screen shots below will help you to develop a page and bind data from a jpa data control.

Steps to build this very simple app.

1.Create database connection in your connection Navigator.

2.Import the tables as entities.

3.right click the imported entity and create a service Facade.
one the facade is created write few lines of code to view your data(it returns in a list ,you can use an iterator..) from the table.

4.Right click the Javaservice facade to create data control.

5.Create a jsf jsp page(this includes adf faces,adf core taga while creating).

6.Drop a panel page from adf tags.

7.select your desired method ,from the data control palette and drop it on the Panel page ,whick will ask you to select the table type(you can choose any type )

8.Rebuild your project.set the default target and the new jsp page you created in step 5 and run the project.

9.You should see the data.

Please let me know if you have issues.

Thanks
Prem