Pages

Tuesday, September 27, 2011

Base64 encoding in Oracle BPEL 11g

Sometimes in SOA Suite 11g you need to pass binary data to a web service reference. In SOA Suite 11g there is no standard XSLT or XPATH function which you can use. But in BEPL you can use embedded java, like Sudheer already blogged about. He used the com.collaxa.common.util.Base64Encoder class which does not exists in 11g so I will use the new oracle.soa.common.util.Base64Encoder class.

As input I will retrieve some xml from the inputVariable, get the xml as a string, encode this and set the value to a base64Binary variable.

Thursday, September 22, 2011

Virtual Users with SAML in WebLogic

A small blogpost how you can use virtual users on your SAML Service Provider WebLogic Server. A virtual user is a user who is authenticated on the SAML Identity Provider and this user is transfered ( with all his attributes and roles )  in a SAML Token to the Service Provider, this user does not need to exists on the WebLogic server of the Service Provider.
Before you can use this feature you need to setup SAML 2.0 SSO on your WebLogic Domain. You can follow this blogpost for all the instructions. You can also do this with Web Services but then you need to follow this guide.

First we need to enable Generate Attributes on the Identity Provider Side.
Go to the myrealm security realm ->  Providers -> Credentials Mapping -> your SAML 2.0 Credential Mapping Provider -> Provider Specific.
Also do this on the imported Service Provider Partner located at the Management tab of your SAML 2.0 Credential Mapping Provider. Open the Service Provider Partner and also enable here Generate Attributes.

Next step is to configure the SAML Service Provider.
Go to the myrealm security realm ->  Providers ->  Authentication -> your SAML 2.0 Identity Assertion Provider -> Management Tab.
Open your imported Identity Provider Partner configuration.
Enable Virtual User and also enable Process Attributes.

Now we need to add an extra WebLogic SAML Authentication Provider. This provider will process the virtual user SAML token with all its attributes and roles.
Set the Control Flag to Sufficient also change the other authentication provider from Required to Sufficient.

That's all.

Monday, September 12, 2011

Calling an OWSM protected service with Axis 1.4 and WSS4J

Not the whole world uses Fusion Middleware so sometimes it is necessary to call an Oracle Web Service Manager protected Web Service from a different java framework like Apache Axis 1.4 combined with WSS4J 1.5. In this blogpost I will show you the steps how to do this.

First you can't use every OWSM policy with Axis. Oracle made an interoperability documentation page what is possible with Axis 1.4 and OWSM 11g, please check this first.

In this post I will use the oracle/wss10_username_token_with_message_protection_service_policy OWSM server policy on a protected OSB proxy service and will call this from axis / wss4j and these frameworks will use the following policies UsernameToken, Timestamp, Signature and Encrypt.

In this demo I will used self signed keys and these are generated by the keytool of java 1.6. Basically I create two keystores and exchange the public keys. The server keystore is imported in the OWSM configuration page and the client keystore will be used in Axis.

keytool -genkey -alias serverKey -keyalg "RSA" -sigalg "SHA1withRSA" -dname "CN=server, C=US" -keypass welcome -keystore c:\temp\server.jks -storepass welcome -validity 3650

keytool -genkey -alias clientKey -keyalg "RSA" -sigalg "SHA1withRSA" -dname "CN=client, C=US" -keypass welcome -keystore c:\temp\client_2.jks -storepass welcome -validity 3650 

keytool -exportcert -alias serverKey -storepass welcome -keystore c:\temp\server.jks -file c:\temp\server.cer

keytool -exportcert -alias clientKey -storepass welcome -keystore c:\temp\client_2.jks -file c:\temp\client.cer

keytool -import -alias serverKey -file c:\temp\server.cer -storepass welcome -keystore c:\temp\client_2.jks keytool -import -alias clientKey -file c:\temp\client.cer -storepass welcome -keystore c:\temp\server.jks 

keytool -list -storepass welcome -keystore c:\temp\client_2.jks
keytool -list -storepass welcome -keystore c:\temp\server.jks

For this policy we also need to create a user called osbbook and with password weblogic1 in the myrealm security realm of WebLogic.

The next step is to check if all is fine by creating an OWSM client in Jdeveloper 11g and using the oracle/wss10_username_token_with_message_protection_client_policy OWSM client policy . First generate a web service client and use the following code to check if it works.


If all is fine we can go to the Axis and WSS4J part.
We need to download the following software frameworks from Apache.

Download the WSDL and it's XML Schemas of the remote service and fix the schema imports of the WSDL. Put these files in your project folder.

The first step is to generate a Web Service Proxy client based on this WSDL, for this we don't use JAX-WS but we will use the AXIS libraries.
Here is the ANT build file to generate the Java classes from WSDL with Axis 1.4,  I put the build.xml in my project folder of JDeveloper.

Add the following libraries to the project. Wss4j-1.5.12.jar, Axis.jar, Jaxrpc.jar, Saaj.jar, Wsdl4j-1.5.1.jar, Commons-discovery-0.2.jar, Commons-logging-1.0.4.jar, Log4j-1.2.8.jar, Javax.activation_1.1.0.0_1-1.jar, Javax.mail_1.1.0.0_1-4-1.jar ,Xmlsec-1.4.5.jar, Xml-apis-1.3.03.jar, Serializer-2.7.1.jar, Xalan-2.7.1.jar, XercesImpl-2.9.1.jar

We also need to create a security property file called crypto.properties and put this in the src folder. This file contains the keystore path with its keystore password.

Create a Password callback class for all the password used in this ws client ( the password of the usernametoken and the keystore passwords )
We also need an Axis deployment file WSDD with the WSS4J configuration, put this file called client_deployment.wsdd in your project folder.

For the response I need to do the following policies Signature, Timestamp and then Encrypt , this is wrong in the documentation

Use the log4j.properties to see all the messages, else you won't see the debug information of WSS4J and Axis 1.4.
Put this file in the src folder.

And at last the Axis test client where we load the client_deployment.wsdd file.

Tuesday, September 6, 2011

Using OWSM Kerberos policies

In this blogpost I will explain how you can use the OWSM ( Oracle Web Service Manager) Kerberos policies in Fusion Middleware 11g. Some of these kerberos policies are compatible with the Window Active Directory KDC and these kerberos tokens can be used for authentication and message protection. It basically works the same as I described in my blog about Windows Single Sign On with web applications deployed on WebLogic. If you want to use OWSM SAML policies instead then you can use this blogpost and for username tokens or certificates protection you can use this blogpost.

OWSM support the following Kerberos server policies.
  • oracle/wss11_kerberos_token_service_policy, this can be used for authentication just like the username token policies. It does not encrypt the message and can be used with AD and MIT
  • oracle/wss11_kerberos_token_with_message_protection_basic128_service_policy, besides the authentication it also encrypts the message. This policy works with AD.
  • oracle/wss11_kerberos_token_with_message_protection_service_policy, this policy does the same but only works with MIT. 
For Windows AD we can only use the first two policies.

Before we can start you need to know or do the following

Know the supported encryption types of your Windows Environment. For example Windows XP or Windows 2003 Domain Controller ( not SP1 ) does not support every encryption type.

I got this working with a Windows 7 client and a Windows 2008 R2 Domain Controller and my encryption type is RC4-HMAC-NT, which is also supported in Java 1.6

My Active Directory domain = ALFA.LOCAL  ( always use it in uppercase )
Make sure that all server can be found in the DNS ( and reverse ) and that the time is synchronized on all machines.

In my test environment I will use 3 servers, The first is my AD 2008 server, second is the OWSM server called soaps3.alfa.local on which we will deploy a kerberos protected JAX-WS service and third is the Web Service Proxy client machine called win7.alfa.local and this has the OWSM kerberos client policy.

We need to create 2 unique service account in Active Directory. In this case soaps3_kerb and win7_kerb and make sure that the passwords of these accounts never expires.

On the Windows 2008 DC server I did the following to generate a service account called HTTP/soaps3.alfa.local and map this to soaps3_kerb AD account. Soaps3 is the server hostname of the WebLogic Server.

First generate a keytab file for the HTTP/soaps3.alfa.local@ALFA.LOCAL account, HTTP is a container ( IIS also uses this convention ) and ALFA.LOCAL is my AD domain.

ktpass -princ HTTP/soaps3.alfa.local@ALFA.LOCAL -pass Welcome01 -mapuser soaps3_kerb@ALFA.LOCAL -out c:\soaps3.keytab -ptype KRB5_NT_PRINCIPAL -crypto RC4-HMAC-NT 

copy the generated soaps3.keytab file to the WebLogic machine ( soaps3 )
I put it in the c:\oracle folder.

Now we need to modify the Service Principal Names with the SPN utility ( Do this on the AD server )
setSpn -A HTTP/soaps3.alfa.local@ALFA.LOCAL soaps3_kerb 

Now we can do the same for the win7 machine, which will be used as ws client.
ktpass -princ HTTP/win7.alfa.local@ALFA.LOCAL -pass Welcome01 -mapuser win7_kerb@ALFA.LOCAL -out c:\win7.keytab -ptype KRB5_NT_PRINCIPAL -crypto RC4-HMAC-NT

copy the win7.keytab to the oracle folder of the win7 machine
setSpn -A HTTP/win7.alfa.local win7_kerb

On the win7 and soapss3 machine we need to create krb5.ini textfile and put this in c:\windows

ALFA.LOCAL is my AD domain and soaps3 is my WebLogic server and it exists in the alfa.local dns domain.
ad-win2008r2.alfa.local is my domain controller.
the krb5.ini for the soaps3 machine
-------------------
[libdefaults]
default_realm = ALFA.LOCAL
default_tkt_enctypes = rc4-hmac
default_tgs_enctypes = rc4-hmac
permitted_enctypes = rc4-hmac

[domain_realm]
.soaps3.alfa.local = ALFA.LOCAL
soaps3.alfa.local = ALFA.LOCAL

[realms]
ALFA.LOCAL = {
    kdc = ad-win2008r2.alfa.local
    admin_server = ad-win2008r2.alfa.local
    default_domain = alfa.local }

[appdefaults]
autologin = true
forward = true
forwardable = true
encrypt = true

---------------

and the win7 machine version.
-----------------

[libdefaults]
default_realm = ALFA.LOCAL
default_tkt_enctypes = rc4-hmac
default_tgs_enctypes = rc4-hmac
permitted_enctypes = rc4-hmac

[domain_realm]
.win7.alfa.local = ALFA.LOCAL
win7.alfa.local = ALFA.LOCAL

[realms]
ALFA.LOCAL = {
kdc = ad-win2008r2.alfa.local
admin_server = ad-win2008r2.alfa.local
default_domain = alfa.local
}
------------------


Go to the JVM bin folder of the the WebLogic server. This is the soaps3 machine. Here we generate a token.

cd c:\oracle\jrockit-jdk1.6.0_26-R28\bin
kinit HTTP/soaps3.alfa.local@ALFA.LOCAL
Provide the password of HTTP/soaps3.alfa.local and the ticket will be stored in your user profile.

Do the same on the win7 machine but then with the use HTTP/win7.alfa.local account.
cd c:\oracle\jrockit-jdk1.6.0_26-R28\bin
kinit HTTP/win7.alfa.local@ALFA.LOCAL

That's all for the kerberos configuration on the windows machines. Now we need to do some configuration in the Enterprise Manager and the WebLogic Console.

First we need to configure the kerberos Login module.
Go the Enterprise Manager (EM) application of the WebLogic server. Open the WebLogic Domain treenode and select your WebLogic domain. In the Domain menu (right window) go to Security -> Security Provider Configuration

Select the krb5.loginmodule and click on the Edit button.

Here we need to provide the principal name HTTP/soaps3.alfa.local@ALFA.LOCAL and its keyTab file.
Save and restart the WebLogic server.

After that we need to create a user on the WebLogic domain or configure an AD ldap authenticator.
The user HTTP/win7.alfa.local must exists on the domain. The password does not matter because it is already authenticated against the AD.


For the server side you can enable the kerberos debugging by adding the following parameter to the EXTRA_JAVA_PROPERTIES parameter in the setDomainEnv.bat of your domain.  -Dsun.security.krb5.debug=true

Deploy the following JAX-WS service on the soaps3 server.


That's all for the server part, now we can test the web service proxy client on the win7 machine.

On the client you can also set the following project options -Dsun.security.krb5.debug=true to see all the debug information. And off course you can use the HTTP analyzer to see all the traffic.

This is my test client code.

When you run the test client you should be authenticated and see the output.

Thursday, September 1, 2011

Using the EJB adapter in SOA Suite 11g

In Oracle SOA Suite 11g you can use the EJB adapter to expose a Remote interface as a Service or use it in a Reference Service.  From PS2 you only need to have an interface jar for the EJB adapter. The interface jar only contains the entities and the Session Bean interfaces (local and remote ) and does not contains the bean or the persistence unit.  Off course you can still generate an SDO interface on the EJB Session and use that in the EJB adapter like I did in this blogpost but this is not necessary.

In this blogpost I will focus on how to use the EJB adapter as a reference service. With this you can think of replacing your database adapters.  Off course you can make some composites in which you expose some database adapters for optimal reuse but maybe it is easier to use an EJB Session Bean deployed on a model tier which can cache your data, is cluster aware and can be also used by your Java (Web) applications.

We start by dropping an EJB adapter on the reference side of the composite.  Lookup the interface jar and provide the remote interface class. Add some text to the JNDI Name, we need to delete this entry and replace it with the right value ( a jdeveloper bug)

Choose for the JAVA interface else you need to have an EJB Session Bean with a SDO interface.

After the creation of the EJB adapter you can select the adapter and optional add some properties( in the property window ) like the java.naming.provider.url in case when the EJB Session Bean is not deployed on the SOA Suite server.

Now go the source mode of your composite where we fix the JNDI url. Delete the uri attribute of the binding.ejb element.

Now we need to add the JNDI name of your EJB Session Bean to the ejb binding. You can select the binding.ejb element and add the jndi url in the property window.

It need to have the jndiName attribute and not the uri attribute.


That's all for the EJB adapter but to use it in a Service Component we need to follow the rules of exposing a java class as a web service. The bottom up approach with JAX-WS like I describe in this blogpost. This is also necessary when you use the EJB transport in the OSB.

We start with the Remote Interface of the EJB Session bean. With the JAX-WS annotations like WebParam, WebMethod or WebResult we can control and influence the WSDL generation.  This WSDL will be used by the Service Components.

If we don't do this you will get arg0 as argument name and return as Response element.

With JPA you can have a reference entity attribute between two entities. For example the employee entity has a department attribute and department has a collection of employees. With this you can create a loop in loading employee and department entities. JPA don't allow this and you can control it with eager of lazy loading.
For JAX-WS and the EJB adapter you need to decide where you want to stop this loading by adding the XmlTransient attribute to a getter. So in this example you can add this to the getDepartment method of the employee entity or add this to the getEmployees of the department entity.


In the WSDL you can see that the employee does not have the department element.

The last important thing is, to avoid the use of java.util.Date, Timestamp or java.sql.Date. This will be ignored by the EJB adapter. You need to use Calendar as java type.