Pages

Showing posts with label OWSM. Show all posts
Showing posts with label OWSM. Show all posts

Saturday, February 25, 2012

Use MySQL 5.5 as MDS database repository in FMW 11g R1 PS5

One of the new features of Fusion Middleware 11G R1 PatchSet 5 (PS5) is the support for MySQL 5.5 as Meta Data Services (MDS) repository. This means you can use MySQL database as a store for ADF personifications or as policies store for your OWSM domain. For MDS you just need a small database which store these configurations. For the SOA infra repository ( not supported on MySQL )  I think the Oracle Database will always be the best choice ( tuning, transactions, RAC ).
This way you add the MySQL database on the same machine as your WebLogic Domain without taking a lot of machine resources, less maintenance or thinking about licensing costs.

In this blogpost I will show you the steps how to create a MDS repository for OWSM and ADF.  

First we start with downloading MySQL 5.5 and install it on a machine. I will use InnoDb as database engine and UTF8 as character set ( this is probably best tested by Oracle).

Add or change the following database settings in the my.cnf of the MySQL database.


innodb_file_per_table
innodb_file_format=Barracuda
innodb_large_prefix
log_bin_trust_function_creators

sql-mode=NO_BACKSLASH_ESCAPES
max_sp_recursion_depth=10

The first 4 settings are required by the RCU installer ( Repository Creation Utility )
The sql-mode is necessary in OWSM else you will get a SQL error ( escape ' \'  on a like ) when you start the WebLogic Domain.
the max_sp_recursion_depth=10 else you will get this error Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine mds_internal_createPackageRecursive

Start the RCU installer and select MySQL Database as database type. I will use root as username cause it needs to create a table ( schema_version_registry)  in the test database  and it wants to create a new database.


MySQL does not support all options but for us, the Metadata Services option is enough. Besides MDS, MySQL is also supports ODI ( Oracle Data Integrator ) and Enterprise Performance Management, I personally don't know these products so I can't test them for you .


RCU creates a dev_mds database and an user dev_mds user.




It will create the following tables


For OWSM, I also created a dev1_mds database with the RCU which I will use in the WebLogic Domain creation ( EM, JRF and OWSM as domain options ) . I used the dev1_mds as database and DEV1_MDS as MySQL username



Now we can start the OWSM WebLogic domain and deploy our protected Web Services.

We can also use it in ADF, for this we need to open the Enterprise Manager application, select your domain and go to Metadata Repositories. Click on Register.


I create a new MySQL user which has access to the test and dev_mds database.


grant all on dev_mds.* to mds@'%' identified by 'welcome';
grant all on test.* to mds@'%' identified by 'welcome';

the test database contains the RCU schema_version_registry table which contains all the entries.

use mds as username and test as service name.


Now you can register  you own MDS database repository.



That's all.

Saturday, February 18, 2012

Identity propagation with OWSM

OWSM allows you to pass on the identity of the authenticated user to your OWSM protected web service ( thanks to OPSS ), this username can then be used by your service. This will work on one or between different WebLogic domains.
For example on the client side you can have an web application which uses ADF Security or Container security, the application calls an web service with the help of a ws proxy client or an ADF ws datacontrol. The web service can be a SOA Suite, OSB proxy or a JAX-WS service.
To make this work we need to use SAML policies, SAML allows us to do identity propagation, other policies won't work because you need to have the password of the authenticated user which you don't have.
Before I show you, how this works, you need to have a SAML OWSM environment, I already did this in this blogpost Do SAML with OWSM , in this I generated some keystores and configured OWSM  on all the WebLogic domains and deployed a web service which has the oracle server wss11_saml_token_with_message_protection_service_policy. In my case I used JAX-WS but it also works on SOA Suite and OSB. When you want to do this on different WebLogic domains then you need to make sure that the user identities exists on both domains ( or you can enable virtual users ).
On the client side which will be in this case an ADF Web Application which is protected by ADF Security. In this application I will use a ADF WS Datacontrol on which we will add the SAML client policy wss11_saml_token_with_message_protection_client_policy.

Create the ADF WS Datacontrol. Select the DataControls.dcx file and select the service in the Structure window.

 Click on "Define Web Service Security".


Select oracle/wss11_saml_token_with_message_protection_client_policy in the security Tab


Override Properties,
these settings will work on the SOA Suite server, if you want to use this on the saml server then you need to use www.amis.nl as saml.issuer.name and samlkey as keystore.recipient.alias.


Deploy the application to the WebLogic Server and you are ready to go.

Thursday, October 6, 2011

Calling an OWSM protected service with Axis2 and Rampart

In a previous blogpost I used Axis 1.4 in combination with WSS4J 1.5 and because Axis 1.4 is getting old so I tried the same with Axis 2 and Rampart which uses WSSJ. For all the security details like the username and how to generate certificates you can check see my previous post.

Just like the Axis 1.4 post I will call a OSB service which has an oracle/wss10_username_token_with_message_protection_service_policy OWSM server policy.

Before we start we need to download axis2 and the matching Rampart version, I use in this blogpost the 1.60 versions of axis2 and Rampart.  Copy the Rampart jars to the axis lib folder and the Rampart modules to the axis2 modules folder.

Download the WSDL with it's XSDs from the Web Service.

After that use this ANT build file to generate a ADB web service proxy client. The wsdl I used has the Customer.wsdl as name.
This OWSM policy have different signing and encryption options on the message of the request / response. So we need to move the right WS security policies / assertions from the Customer WSDL to a Request and Response policy file.

Here is the Request Policy which matches with the oracle/wss10_username_token_with_message_protection_service_policy Server policy. I also added the Rampart Configuration which contains references to the keystore and the username I used. Add the sp:AsymmetricBinding, sp:SignedSupportingTokens and the sp:SignedParts & sp:EncryptedParts of the request from the customer wsdl to this policy file.
We also need to do this for the Response. Add the sp:AsymmetricBinding and the sp:SignedParts & sp:EncryptedParts of the response from the customer wsdl to this policy file.
Because we are using a keystore and a username token ( which got passwords ) we need to add a Password Callback class.
And here the test client which loads the Axis2 configuration with the Addressing and Rampart modules and also loads the Request and Response policy.
Here you can download my code at https://github.com/biemond/soa11g_examples/tree/master/OWSM_AXIS



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.

Friday, August 26, 2011

Single Sign On with windows / kerberos on WebLogic

In this blogspot I will show you the steps I did to achieve SSO kerberos windows authentication on an ADF or a Web Application deployed on a WebLogic application server.

Before we can start you should 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.

We start by creating a unique service account ( it must not exists, not as computer and not as an user ), in my case is that soaps3_kerb.


I used Welcome01 as password and make sure that the password 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 name 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

my output
Targeting domain controller: AD-WIN2008R2.alfa.local

Using legacy password setting method
Successfully mapped HTTP/soaps3.alfa.local to soaps3_kerb.Key created.
Output keytab to c:\soaps3.keytab:
Keytab version: 0x502
keysize 68 HTTP/soaps3.alfa.local@ALFA.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x17 (RC4-HMAC) keylength 16 (0x1d863479e1ab3bd62a2bfafa1abaa2dd)


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

Now we need to modify the Service Principal Names with the SPN utility.
setSpn -A HTTP/soaps3.alfa.local@ALFA.LOCAL soaps3_kerb

my output
Registering ServicePrincipalNames for CN=soaps3_kerb,CN=Users,DC=alfa,DC=local
        HTTP/soaps3.alfa.local@ALFA.LOCAL
Updated object



Now we can continue with the WebLogic Server configuration.

Start by making create a text file called krb5.ini and put it 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.
-------------------

[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
.alfa.local = ALFA.LOCAL
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

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

On the soaps3 WebLogic machine we need to create a new Kerberos ticket which will be used by WebLogic.

First let's flush the current ones
go to c:\ ( not in the java bin folder )
klist purge

go to the bin folder of your java home ( jdk )
cd c:\oracle\jrockit-jdk1.6.0_26-R28\bin

kinit HTTP/soaps3.alfa.local@ALFA.LOCAL

My output
Password for HTTP/soaps3.alfa.local@ALFA.LOCAL:
New ticket is stored in cache file C:\Users\admin\krb5cc_admin


This should work and it will use the krb5.ini located at c:\windows.


Create or change an application with ADF Security or a normal Web Application which got security enabled. Open the web.xml and change the auth-method to CLIENT-CERT


  <login-config>
    <auth-method>CLIENT-CERT</auth-method>
  </login-config>


Deploy the application to the WebLogic Server.

Open the WebLogic console application and go to myrealm security realm -&gt; providers -&gt; authentication.

create a NegotiateIdentityAsserter called Microsoft.


Open the NegotiateIdentityAsserter and go to Provider Specific and de-select Form Based Negotiation Enabled.

Next step is to create a kerberos login configuration which will be read by WebLogic.
Create a text file called kerberos.login located in the c:\oracle. This is the content which will work with Java 1.6
-------

com.sun.security.jgss.krb5.initiate {
     com.sun.security.auth.module.Krb5LoginModule required
     principal="HTTP/soaps3.alfa.local@ALFA.LOCAL"
     useKeyTab=true
     keyTab="c:/oracle/soaps3.keytab"
     storeKey=true
     debug=true;
};

com.sun.security.jgss.krb5.accept {
     com.sun.security.auth.module.Krb5LoginModule required
     principal="HTTP/soaps3.alfa.local@ALFA.LOCAL"
     useKeyTab=true
     keyTab="c:/oracle/soaps3.keytab"
     storeKey=true
     debug=true;
};
-------

Add the following parameters to the EXTRA_JAVA_PROPERTIES in the setDomainEnv.bat of your domain.
-Dsun.security.krb5.debug=true 
-Djavax.security.auth.useSubjectCredsOnly=false 
-Djava.security.auth.login.config=C:/oracle/kerberos.login 
-Djava.security.krb5.realm=ALFA.LOCAL 
-Djava.security.krb5.kdc=ad-win2008r2.alfa.local 


We are finished with the WebLogic and the AD configuration.

Just add the login name of the window user and its groups to the myrealm security realm, so you can test the Web Application.

Log on a machine which is part of your AD domain.

use Internet Explorer and trust the weblogic site and enable authentication in the advanced options of IE.
or
use Google Chrome and start chrome.exe with the following parameter --args --auth-server-whitelist="*alfa.local" This allows SSO with chrome.


Monday, August 22, 2011

Do SAML with OWSM

In this blogpost I will explain the different SAML options and the advanced configurations you can do when you use the SAML client and server policies of Oracle Web Service Manager FMW 11gR1.
The following will be explained and configured in this blogpost.
  • A basic SAML authentication with 2 OWSM Servers.
  • Change the default SAML issuer name.
  • Allow only trusted SAML clients.
  • SAML Identity switching.
  • Virtual Users with User roles.
Creating a working SAML setup. 
For this we need two WebLogic domains and both have at least the Enterprise Manager web application and enabled the OWSM option. For this demo I will have one domain with SOA Suite and one with only a WebLogic Adminserver where we will deploy a JAX-WS Web Service which has an OWSM server policy. You can replace the SOA Suite with a OSB server ( it works in the same way ) . For OWSM, every domain need to have it's own MDS repository to store all the OWSM policies and for SOA Suite you also need a soa-infra database repos.

This will be our setup.
  • A client ( soapUI or WS client proxy ) calls an exposed web service of a SOA Suite composite and the client needs to provide a username token.
  • The exposed service has oracle/wss_username_token_service_policy as OWSM Server policy. The username token will be validated by WebLogic and the username will be passed on by SAML and signed with the signing certificate of the SOA Suite OWSM. The exposed service has a wire to a Mediator with a simple routing rule.
  • The Mediator has a wire to the Reference Web Service. This reference WS binding has oracle/wss11_saml_token_with_message_protection_client_policy as OWSM client policy.
  • The Reference WS binding calls a JAX-WS Web Service deployed on the other WebLogic Domain and this Web Service has oracle/wss11_saml_token_with_message_protection_service_policy as OWSM server policy. OWSM will validate the SAML issuer and check if it knows the username ( the password does not matter, because it is trusted )
The SOA Composite I used.

The JAX-WS service
Before we can test this SAML service, we need to generate some keystores, configure OWSM and add some users to WebLogic.
Execute the following commands to generate some self signed private keys and exchange the public keys ( this will trust each other certificates )

Go to the bin folder of your JDK.
cd c:\oracle\jrockit-jdk1.6.0_26-R28\bin

Generate a certificate for SOA ( server.jks ) and one for the JAX-WS server (  saml.jks )
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 samlKey -keyalg "RSA" -sigalg "SHA1withRSA" -dname "CN=saml, C=US" -keypass welcome -keystore c:\temp\saml.jks -storepass welcome  -validity 3650

Export the public key
keytool -exportcert -alias serverKey -storepass welcome -keystore c:\temp\server.jks -file c:\temp\server.cer
keytool -exportcert -alias samlKey -storepass welcome -keystore c:\temp\saml.jks -file c:\temp\saml.cer

Import the keys in each other keystore ( for the trust (
keytool -import -alias serverKey -file c:\temp\server.cer -storepass welcome -keystore c:\temp\saml.jks
keytool -import -alias samlKey -file c:\temp\saml.cer -storepass welcome -keystore c:\temp\server.jks

Show the certificates in each keystore.
keytool -list -storepass welcome -keystore c:\temp\server.jks
keytool -list -storepass welcome -keystore c:\temp\saml.jks

Copy the server.jks to the config\fmwconfig folder of your SOA Suite domain. Do the same for the saml.jks keystore but then to fmwconfig of the JAX-WS server domain.

Go the Enterprise Manager (EM) application of the SOA Suite.  Open the WebLogic Domain treenode and select your SOA domain. In the Domain menu (right window)  go to Security -&amp;gt; Security Provider Configuration. Click on the Configure button in the keystore section.

  
Use ./server.jks in the Keystore Path field and serverKey in the Key and Crypt Alias. Use welcome for all the password fields.

We need to do the same at the JAX-WS server but then use the following values.
Use ./saml.jks in the Keystore Path field and samlKey in the Key and Crypt Alias. Use welcome for all the password fields.

Add a user with client as name and with weblogic1 as password in the myrealm security realm of the SOA Suite server. Do the same at the JAX-WS server but now use welcome1 as password.

Do a restart of the all the servers.

We can test the SAML setup by generating a Web Service Client proxy in JDeveloper. Here is an example how I add the client credentials.

that is all for the basic SAML test.

How to change the SAML issuer name. 
The default SAML issuer name is www.oracle.com , We can change this at the JAX-WS server. For this we need to go the EM application of the JAX-WS Server. Open the WebLogic Domain treenode and select your JAX-WS domain. In the Domain menu (right window)  go to Security -> Security Provider Configuration. Click on the Configure button in the Advanced section.

Here we can change the name attribute of saml.trusted.issuers.1 property to www.amis.nl and click on Ok. This way you will change the default trusted issuer for all the SAML login modules, if you only want to change this for SAML1.1 and not for SAML2 then you can open the saml.loginmodule instead (located at the Security Provider Configuration) and change it there. This will add an extra saml property name beside the one of www.oracle.com
You will need to restart the WebLogic server.

We also need to change an attribute on the reference web service binding of the SOA Composite. Select the reference binding and right click, to open the Configure WS Policies menu.

Click on the pencil to override the saml.issuer.name and use www.amis.nl

Deploy the composite and re-test it with the jdeveloper ws proxy client.

Allow only trusted SAML clients
In the current setup each public key found in the saml.jks keystore can sign a SAML token. In this part we can restrict this to only "CN=server, C=US", this is the DN of the signing certificate located at the SOA Suite server.

Go the Enterprise Manager (EM) application of the JAX-WS Server.  Open the WebLogic Domain treenode and select your JAX-WS domain. In the Domain menu (right window)  go to Web Services -> Platform Policy Configuration.

Go to the Trusted SAML clients Tab and add a new Trusted Issuer called www.amis.nl .
Select the just created Trusted Issuer and add a Trusted SAML Client and use CN=server, C=US as value.

Restart the JAX-WS Server and now only CN=server, C=US can sign the SAML token.

SAML Identity switching
In the last part of this blogpost we will change the identity of the SAML token. In the previous examples we used client as username and this is passed on to the JAX-WS server.  We will override this on the SOA Suite server.  In our test client we can now use weblogic as username and override to client in the SOA Composite.
Open the Mediator of the  SOA Composite where we will add an Assign to the request part of the Routing Rule.

Here we need to add the javax.xml.ws.security.auth.username property with client as value.

We also need to change the OWSM client policy to oracle/wss11_saml_token_identity_switch_with_message_protection_client_policy on the reference web service binding.

Deploy your composite.

Too bad, this is not enough we also need to give my SOA Composite the right permissions to do identity switching. Go the Enterprise Manager (EM) application of the SOA Suite.  Open the WebLogic Domain treenode and select your SOA domain. In the Domain menu (right window)  go to Security -> System Policies.

Select Codebase as Type and search. Select a Codebase policy and do Create Like.

Use file:${common.components.home}/modules/oracle.wsm.agent.common_11.1.1/wsm-agent-core.jar as value in the Codebase field and click on Edit.

Enter oracle.wsm.security.WSIdentityPermission in the Permission Class field. The action is always assert. The Resource Name is your Composite Name which does the identity switching.


Virtual Users with User roles
The last part is virtual users, in this section will we add some roles and change some attributes on the SOA Suite client user. Change the policy back on the composite reference ( oracle/wss11_saml_token_with_message_protection_client_policy ) and also use client as username in the web service proxy client.

First change some client user attributes. We can do this in the security realm of the SOA Suite WebLogic Domain.


Normally the user is only mapped to the user located at the JAX-WS server. To make virtual servers work we need to add a property to the saml.loginmodule located at the JAX-WS server.  For this we need to go the EM application of the JAX-WS Server. Open the WebLogic Domain treenode and select your JAX-WS domain. In the Domain menu (right window)  go to Security -> Security Provider Configuration.

Click on Edit and add a custom property oracle.security.jps.assert.saml.identity with value true.


Restart the JAX-WS WebLogic server.

We also need to do something in the SOA Composite.
Override the following properties

user.attributes with value  displayname,employeenumber ( use , to separate ldap attributes you want to pass on )
user.roles.include with value true
subject.precedence with value true

Deploy the composite and when you test your test client. You will see the following output on the JAX-WS Server.


virtual found
saml issuer: www.amis.nl

SAML attribute: employeenumber
value: 100

SAML attribute: Roles
value: Operators
value: AdminChannelUsers
value: IntegrationOperators
value: IntegrationMonitors
value: Monitors

SAML attribute: displayname
value: SAML client





Saturday, August 21, 2010

The things you need to do for OWSM 11g policies

In Fusion Middleware 11g it is not so difficult to protect your JAX-WS Web services or your Composite Services. You just need to add an Oracle Web Service Manager service policy to this Web Service. So that's all the work for the developer or release manager. And now the work starts for the Administrator. This persons need to be familiar with the Enterprise Manager, WebLogic Console, OpenSLL and with the keytool utility of the JDK. In this blogpost I will show what you need to do if you choose for a particular OWSM Policy.


Let's start simple with one of the following policies
oracle/wss_http_token_service_policy
oracle/wss_username_token_service_policy

These policies can be used for HTTP Basic Authentication or for an Username Token in a SOAP message. The only thing you need to do for these policies is to add some Users to the myrealm Security Realm in the WebLogic Console.
On the client side you need to do the following.
execute = new Execute();
SecurityPolicyFeature[] securityFeatures =
            new SecurityPolicyFeature[] { new SecurityPolicyFeature("oracle/wss_username_token_client_policy") };
Request_Response_ptt request_Response_ptt = execute.getRequest_Response_pt(securityFeatures);
    
// Add your code to call the desired methods.
Map<String, Object> reqContext = ((BindingProvider) request_Response_ptt).getRequestContext();
reqContext.put(BindingProvider.USERNAME_PROPERTY, "test" );
reqContext.put(BindingProvider.PASSWORD_PROPERTY, "weblogic1" );
       
Request req = new Request();
req.setName("edwin");
req.setMessage("hi");
Response resp = request_Response_ptt.requestResponse(req);


The Message protection policies
oracle/wss10_message_protection_service_policy
oracle/wss11_message_protection_service_policy
When you choose for one of these policies you need to generate a Server certificate for encryption and put this in a Java keystore and for the Client side you also need to make a Keystore but this contains only the public key of this Server encryption certificate ( this is in case of the wss11, for the wss10 you also need to generate a client certificate besides the public key of server, see the x509_token_with_message_protection policies how to do this. ).

To add your Server keystore to FMW, you need to go to the Enterprise Manager and select your Weblogic Domain. In the menu go to the Security / Security Provider Configuration page. And on this page you can import your Java keystore. Before you start you need to copy your keystore to your domain folder and put this in the config/fmwconfig folder.

In this example I used two certificates one for the signature and one for the encryption. For the wss11 Message protection Service policies you only need the encryption certificate.
On the client side you need to load the client keystore and the public key of server encryption certificate. 
execute = new Execute();
SecurityPolicyFeature[] securityFeatures =
    new SecurityPolicyFeature[] { new SecurityPolicyFeature("oracle/wss11_message_protection_client_policy") };
Request_Response_ptt request_Response_ptt = execute.getRequest_Response_pt(securityFeatures);
// Add your code to call the desired methods.
Map<String, Object> reqContext = ((BindingProvider) request_Response_ptt).getRequestContext();

reqContext.put(ClientConstants.WSSEC_KEYSTORE_TYPE, "JKS");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_LOCATION, "C:/client_keystore.jks");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_PASSWORD, "welcome");

reqContext.put(ClientConstants.WSSEC_ENC_KEY_ALIAS, "server_encr");
reqContext.put(ClientConstants.WSSEC_ENC_KEY_PASSWORD, "welcome");
reqContext.put(ClientConstants.WSSEC_RECIPIENT_KEY_ALIAS, "server_encr");

Request req = new Request();
req.setName("edwin");
req.setMessage("hi");
Response resp = request_Response_ptt.requestResponse(req);
For the wss10_message_protection_service_policy you need to do the following.
execute = new Execute();
SecurityPolicyFeature[] securityFeatures =
    new SecurityPolicyFeature[] { new SecurityPolicyFeature("oracle/wss10_message_protection_client_policy") };
Request_Response_ptt request_Response_ptt = execute.getRequest_Response_pt(securityFeatures);
// Add your code to call the desired methods.
Map<String, Object> reqContext = ((BindingProvider) request_Response_ptt).getRequestContext();

reqContext.put(ClientConstants.WSSEC_KEYSTORE_TYPE, "JKS");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_LOCATION, "C:/client_keystore.jks");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_PASSWORD, "welcome");

reqContext.put(ClientConstants.WSSEC_ENC_KEY_ALIAS, "client1");
reqContext.put(ClientConstants.WSSEC_ENC_KEY_PASSWORD, "welcome");
reqContext.put(ClientConstants.WSSEC_RECIPIENT_KEY_ALIAS, "server_encr");

reqContext.put(ClientConstants.WSSEC_SIG_KEY_ALIAS, "client1");  
reqContext.put(ClientConstants.WSSEC_SIG_KEY_PASSWORD, "welcome");

Request req = new Request();
req.setName("edwin");
req.setMessage("hi");
Response resp = request_Response_ptt.requestResponse(req);

The above policies can also be combined. Like in these policies.
oracle/wss10_username_token_with_message_protection_service_policy
oracle/wss11_username_token_with_message_protection_service_policy


For these policies you need to a create user in the WebLogic Console for the username token and generate a server and client keystore for the message protection part.
On the client side you need to the following.
execute = new Execute();
SecurityPolicyFeature[] securityFeatures =
    new SecurityPolicyFeature[] { new SecurityPolicyFeature("oracle/wss11_username_token_with_message_protection_client_policy") };
Request_Response_ptt request_Response_ptt = execute.getRequest_Response_pt(securityFeatures);
// Add your code to call the desired methods.
Map<String, Object> reqContext = ((BindingProvider) request_Response_ptt).getRequestContext();
reqContext.put(BindingProvider.USERNAME_PROPERTY, "test" );
reqContext.put(BindingProvider.PASSWORD_PROPERTY, "weblogic1" );

reqContext.put(ClientConstants.WSSEC_KEYSTORE_TYPE, "JKS");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_LOCATION, "C:/client_keystore.jks");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_PASSWORD, "welcome");

reqContext.put(ClientConstants.WSSEC_ENC_KEY_ALIAS, "server_encr");
reqContext.put(ClientConstants.WSSEC_ENC_KEY_PASSWORD, "welcome");
reqContext.put(ClientConstants.WSSEC_RECIPIENT_KEY_ALIAS, "server_encr");

Request req = new Request();
req.setName("edwin");
req.setMessage("hi");
Response resp = request_Response_ptt.requestResponse(req);
For the wss10_username_token_with_message_protection_service_policy you need to do the following. ( and a need a client certificate and the public key of the server )
execute = new Execute();
SecurityPolicyFeature[] securityFeatures =
    new SecurityPolicyFeature[] { new SecurityPolicyFeature("oracle/wss10_username_token_with_message_protection_client_policy") };
Request_Response_ptt request_Response_ptt = execute.getRequest_Response_pt(securityFeatures);
// Add your code to call the desired methods.
Map<String, Object> reqContext = ((BindingProvider) request_Response_ptt).getRequestContext();

reqContext.put(BindingProvider.USERNAME_PROPERTY, "test" );
reqContext.put(BindingProvider.PASSWORD_PROPERTY, "weblogic1" );

reqContext.put(ClientConstants.WSSEC_KEYSTORE_TYPE, "JKS");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_LOCATION, "C:/client_keystore.jks");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_PASSWORD, "welcome");

reqContext.put(ClientConstants.WSSEC_ENC_KEY_ALIAS, "client1");
reqContext.put(ClientConstants.WSSEC_ENC_KEY_PASSWORD, "welcome");
reqContext.put(ClientConstants.WSSEC_RECIPIENT_KEY_ALIAS, "server_encr");

reqContext.put(ClientConstants.WSSEC_SIG_KEY_ALIAS, "client1");  
reqContext.put(ClientConstants.WSSEC_SIG_KEY_PASSWORD, "welcome");

Request req = new Request();
req.setName("edwin");
req.setMessage("hi");
Response resp = request_Response_ptt.requestResponse(req);

The last part of this blogpost I will explain the following policies
oracle/wss10_x509_token_with_message_protection_service_policy
oracle/wss11_x509_token_with_message_protection_service_policy

These policies will use the client certificate for the signature and the public key of the server encryption certificate for the encryption.
So we start by making some keystores with some certificates. I don't use self signed certificates because then for every new client I need to update the server keystore and reboot the FMW server. Now I only have to import the CA public certificate in the Server keystore. This is how my Server keystore looks like

It got a private certificate for the server signature and for encryption. The CA public key is trusted.

For the client I have this keystore. ( Every customer / application can have its own client keystore )

The CA and Server encryption certificates are public certificates and are trusted.
Because the FMW Server does not know this client certificate ( it only knows the CA ) you need to add a new user in the myrealm Secuirty Realm in the WebLogic Console. The password of this user is not important, the only requirement is that the common name of this client certificate is the same as the WebLogic Username.

And as last the Client code, where we need to provide the client signature certificate details.
execute = new Execute();
SecurityPolicyFeature[] securityFeatures =
    new SecurityPolicyFeature[] { new SecurityPolicyFeature("oracle/wss11_x509_token_with_message_protection_client_policy") };
Request_Response_ptt request_Response_ptt = execute.getRequest_Response_pt(securityFeatures);
// Add your code to call the desired methods.
Map<String, Object> reqContext = ((BindingProvider) request_Response_ptt).getRequestContext();

reqContext.put(ClientConstants.WSSEC_KEYSTORE_TYPE, "JKS");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_LOCATION, "C:/client_keystore.jks");
reqContext.put(ClientConstants.WSSEC_KEYSTORE_PASSWORD, "welcome");

reqContext.put(ClientConstants.WSSEC_SIG_KEY_ALIAS, "client1");
reqContext.put(ClientConstants.WSSEC_SIG_KEY_PASSWORD, "welcome");

reqContext.put(ClientConstants.WSSEC_ENC_KEY_ALIAS, "server_encr");
reqContext.put(ClientConstants.WSSEC_ENC_KEY_PASSWORD, "welcome");
reqContext.put(ClientConstants.WSSEC_RECIPIENT_KEY_ALIAS, "server_encr");

Request req = new Request();
req.setName("edwin");
req.setMessage("hi");
Response resp = request_Response_ptt.requestResponse(req);

For OWSM SAML policies see this blogpost

For OWSM kerberos policies see this blogpost

Wednesday, August 18, 2010

HTTP Basic authentication with SOA Suite 11g

There can be situations where you need to add some security like HTTP basic authentication to your Composite Services or References. Especially when you have some HTTP Binding Services or References. The HTTP Binding Service in SOA Suite 11g also has a SOAP endpoint beside the HTTP endpoint. With the SOAP endpoint you can always use WS-Security instead of the basic authentication, but if that was the case you won't choose for the HTTP Binding.    
For this blogpost I will use my http binding example of this blogpost 
In this example I have a Mediator with a HTTP Binding Reference. This reference has as endpoint the execute url of the Execute HTTP Binding Service, which is connected to the BPEL Component.
Select the execute Service and configure SOA WS Policies, Here you need to select the oracle/wss_http_token_service_policy . This OWSM policy enables HTTP Basic authentication for HTTP  & SOAP or WSS Username Token in SOAP.

For the Composite Reference you need to use the oracle/wss_http_token_client_policy.

Off course you need to provide the username / password for the basic authentication.  To do this you need to go to the Enterprise Manager Application and select your WebLogic Domain. In the Menu, select the Security menu Item and then go to Credentials.

When you don't have the oracle.wsm.security Map then you need to create this. In the Map you need to add the basic credentials Key where you can provide the username / password for the HTTP Binding Service and Reference.
After rebooting the SOA Server you can test this HTTP Binding Service. I use Wfetch of Microsoft. The internal tester client of WebLogic and Enterprise is not so great with HTTP posts and security.

First test is a POST on the HTTP endpoint with a bad username.  This gives a HTTP 403 Forbidden.
Now with a good username / password and for the POST I only have to provide the request in the body and without the SOAP envelop.

The HTTP Binding service also has a SOAP Endpoint. First we test this with a bad username.


Now with a good username / password. For the SOAP post you need to provide the Content-Type and SOAPAction HTTP Headers and the SOAP envelope with the request.

That's all.

Update by Maarten van Luijtelaar
You can have more than one account on the reference level by overriding the oracle/wss_http_token_client_policy properties. By default the value of csf-key is set to basic.credentials, but you can create a new key in EM and use that as an override.
Also, when not using the policy, adding the properties oracle.webservices.auth.username and oracle.webservices.auth.password with corresponding values will do the trick on external references.

Sunday, May 2, 2010

WSM in FMW 11g Patch Set 2 and OSB 11g

With all the Fusion Middleware releases of late April 2010 its nice to take a look at the security part of FMW & OSB 11g. You may already know FMW 11g Patch Set 2 is a patch on PS1 which was a full release but OSB 11g is a new release. Lets see if Oracle changed WSM in PS2 and what they did with the Weblogic 9.2 WS-Security policies in OSB 11g.
Lets start with WSM  in PS2, I did some checks and came to the conclusion that it works the same as in PS1, so my WSM in FMW blogpost is still valid. The only thing what changed is that JDeveloper 11g PS2 give you more information about the WSM policies.
   
OSB11g is a major release and in this 11g release Oracle did not change the WS-Security policies of  Weblogic 9.2, so my OSB blogpost about the security policies in OSB 10.3 is still valid in the 11g version. From this you can conclude Oracle is going full for WSM. With OSB 11g Oracle added support for WSM agents. You can now use the WSM server policies on your OSB Proxy services and the WSM client policies on the OSB Business services. But more inportant, it is now easy to call these secured WSM proxy services from other FMW components ( ADF , Soa Suite & Java )
To use WSM in OSB 11g you need to have a MDS repository and extend the OSB Domain with the WSM components.
When your OSB server is running then you can add the WSM server policy to a Proxy Service. Just select the OWSM policy option and add the right WSM server policy

It works the same for an OSB business service only now you use the client policies.
Before you can test these WSM policies you need to follow the steps of  my FMW WSM blogpost . If you configured the WSM keystore then you can test the proxy service in the service bus console application ( sbconsole) . In the security part of this testpage you only  need to provide the keystore.recipient.alias. Leave the rest empty.

Or you can generate a web service proxy service in JDeveloper and use this in your Proxy client.
public class HelloWorldServiceSoapHttpPortClient
{
  @WebServiceRef
  private static HelloWorldService_Service helloWorldService_Service;

  public static void main(String [] args)
  {
    helloWorldService_Service = new HelloWorldService_Service();
        SecurityPolicyFeature[] securityFeatures =
            new SecurityPolicyFeature[] { new SecurityPolicyFeature("oracle/wss10_message_protection_client_policy") };
        HelloWorldService helloWorldService = helloWorldService_Service.getHelloWorldServiceSoapHttpPort(securityFeatures);
        // Add your code to call the desired methods.

        Map<String, Object> reqContext = ((BindingProvider) helloWorldService).getRequestContext();
        reqContext.put(ClientConstants.WSSEC_KEYSTORE_TYPE, "JKS");
        reqContext.put(ClientConstants.WSSEC_KEYSTORE_LOCATION, "C:\\test_keystore.jks");
        reqContext.put(ClientConstants.WSSEC_KEYSTORE_PASSWORD, "password");
        reqContext.put(ClientConstants.WSSEC_SIG_KEY_ALIAS, "client_key");
        reqContext.put(ClientConstants.WSSEC_SIG_KEY_PASSWORD, "password");
        reqContext.put(ClientConstants.WSSEC_ENC_KEY_ALIAS, "client_key");
        reqContext.put(ClientConstants.WSSEC_ENC_KEY_PASSWORD, "password");
        reqContext.put(ClientConstants.WSSEC_RECIPIENT_KEY_ALIAS, "client_key");
        

        System.out.println(helloWorldService.sayHello());

  }
}