Monday, April 11, 2011

OAM 11g Single Sign-On and OAM 11g Cookies

This post is part of a larger series on Oracle Access Manager 11g called Oracle Access Manager Academy. An index to the entire series with links to each of the separate posts is available.

Our compatriot Eric Leach over at the Oracle Access Management Blog wrote a post describing how SSO works in OAM 11g. It's a great post and fills in all sorts of details about the cookies used, how they're named and how all of the parts fit together. OAM 11g supports a few different PEPs - OSSO, OAM 10g and OAM 11g and Eric discusses them all.

but...

I find a pretty picture much more understandable than a great big blob of text. Part of it is that I'm more of a visual person and part of it is that I tend to get distracted easily. Plus if you're already familiar with OSSO or OAM 10g you probably already know what their cookies look like. So for the purposes of this post I'm only going talk about OAM 11g Server and the 11g WebGate cookies when you do an "HTML form" style login.

Basically if you want the contents Eric's post in pretty pictures and simplified down to include only the 11g cookies then this post is for you!

Wednesday, April 6, 2011

A quick introduction

Hey there!

My name is Andre Correa and I am joining the fusionsecurity blog.
It is really a pleasure to join such an amazing group of professionals. Thank you fusionsecurity bloggers for the invite!
I hope to keep the standards, contribute and share my experiences on the security aspects of Oracle Fusion Middleware.
I was blogging alone on http://secureandgo.blogspot.com/ and got all my posts imported here.

For your convenience, here is the direct link to each of them:


Cheers,

Andre.

Using Apache to simulate an SSL Load balancer

Last week I needed to duplicate a customer's OAM 11g environment to help understand and resolve a problem they were having and needed to simulate a config that looks like this:

The numbers indicate the TCP port used on the server side. All of the red lines are HTTP. The green line (from OHS to the OAM Server) is the OAM NAP protocol.

Unfortunately I don't have a load balancer (an F5 in this particular case) handy so I needed to be a bit creative. Apache, mod_proxy and a little elbow grease can do much the same thing for simple testing purposes. In case you ever need to do the same thing here's a quick setup you can copy/paste to get you going.

SSLProxyEngine on
<Proxy *>
   Order deny,allow
   Allow from all
</Proxy>

RewriteEngine on
ProxyPreserveHost on

NameVirtualHost *:443

<VirtualHost *:443>
  ServerName login.oracledemo.com

  SSLEngine on
  SSLProtocol all -SSLv2
  SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
  SSLCertificateFile /home/oracle/simpleCA/login.oracledemo.com.crt
  SSLCertificateKeyFile /home/oracle/simpleCA/login.oracledemo.com.key

  ProxyPass / http://localhost:14100/
  ProxyPassReverse / http://localhost:14100/
</VirtualHost>

<VirtualHost *:443>
  ServerName idm11g.oracledemo.com

  SSLEngine on
  SSLProtocol all -SSLv2
  SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
  SSLCertificateFile /home/oracle/simpleCA/idm11g.oracledemo.com.crt
  SSLCertificateKeyFile /home/oracle/simpleCA/idm11g.oracledemo.com.key

  RequestHeader set IS_SSL ssl

  ProxyPass / http://localhost:7777/
  ProxyPassReverse / http://localhost:7777/
</VirtualHost>

There are a couple of interesting bits in that configuration...

First is that when you use mod_proxy Apache will use the host name in the URL specified in ProxyPass when it talks to the back end server. In this case that means that the OHS server would see a request with a host header that said "localhost:7777". Which can confuse the application and isn't at all what a conventional load balancer would do. Adding "ProxyPreserveHost on" to the configuration makes mod_proxy use the same name when it talks to the backend server (again OHS in my case) as the browser sent in the original request.

The other interesting thing there is that fact that I'm using NameVirtualHosts over SSL. Yeah, wait, wuh?! I can hear you now - I didn't think you could do that!

I thought the same thing until a few months ago when I stumbled across something called Server Name Indication. When SSL was first created IP addresses were freely available and nobody had invented name-based virtual hosting. As a result the initial SSL design didn't have the client send the requested host name as part of the initial handshake, and as a result the server had no way to know which certificate to send to the client.

Fast forward a few years and the situation has changed quite a bit. We're basically out of IPv4 addresses and name-based virtual hosting is practically the norm. The smart folks in charge of protocols and standards decided it was high time to fix that little oversight. RFC 3546 from June of 2003 documents the details.

Anyway, the only reason I go into all of that is to offer a warning: SSL protected Name-based virtual hosts **DO NOT** work with Internet Explorer on Windows XP. I know XP is on the downswing, but it still has something like 50% of the browser market share according to the first few hits I found a quick Google search.

Hope this helps someone else!

Tuesday, April 5, 2011

A dead simple certificate authority for testing purposes

I don't know about you, but I know I'd rather spend an hour writing a script to automate something than 30 minutes figuring out how to use an existing but annoying/terrible tool. I do that not because I am a glutton for punishment, but because I know I'll have to use that terrible tool again in the future and I won't remember how to use it anyway.

So when I needed certificates for a test environment I checked out OpenSSL's built in CA tool, quickly decided against using it, and then wrote my own simpler tool.

Enjoy!

Update: There's a new version of this script available in a new post

Monday, April 4, 2011

Identity Propagation from App to Data Tier

In order to have the ability to audit at all layers of your multi-tier architecture, it is important to have a Subject’s identity tied to all transactions. Many apps leverage JDBC connection pooling however, so a Subject’s identity is lost at the data layer, as everything appears to be coming from the system user configured in the connection pool. What isn’t well known is that the ability to propagate identity from an app container to the data tier is available within the Oracle JDBC libraries, both thin and OCI-based. One can configure a connection pool using a system user, and create a session with proxy user using the app container’s identity. Example snippet:

<%@ page language="java" contentType="text/html;charset=UTF-8"%>

<%@ page import="javax.naming.*,java.sql.*,oracle.jdbc.pool.OracleDataSource, java.util.*,oracle.jdbc.OracleConnection,javax.sql.DataSource,

java.io.PrintWriter"%>

try {

Context ic = new InitialContext();

DataSource dataSource =

(DataSource) ic.lookup("icam/sampledata");

Properties userNameProp = new Properties();

userNameProp.put(OracleConnection.PROXY_USER_NAME, request.getUserPrincipal().getName());

OracleConnection conn = (OracleConnection)dataSource.getConnection();

conn.openProxySession(OracleConnection.PROXYTYPE_USER_NAME, userNameProp);

PreparedStatement userenvStmt =

conn.prepareStatement(

" select "

+"sys_context('USERENV','PROXY_USER') "

+", sys_context('USERENV','external_name') "

+", sys_context('USERENV','SESSION_USER') "

+", sys_context('USERENV', 'ENTERPRISE_IDENTITY') "

+" from dual"

);

ResultSet userenvRset =

userenvStmt.executeQuery();

if (userenvRset.next()) {

out.println("

Userenv proxy_user : " +

userenvRset.getString(1) + "");

out.println("

Userenv external_name : " +

userenvRset.getString(2)+ "");

out.println("

Userenv session_user : " +

userenvRset.getString(3)+ "");

out.println("

Userenv ENTERPRISE_IDENTITY: " +

userenvRset.getString(4)+ "");

}

userenvStmt.close();

This code assumes that the database is also configured to use Enterprise User Security (EUS), which ensures that the identity is consistent across the app container and database. The app container, WebLogic in this case, is configured to use an LDAP authentication provider.




The diagram shows OID as the LDAP store, but this could also be OVD combined with ODSEE or AD.

One would setup a shared schema in the database to map these proxy users to a database:

CREATE USER sharedschema IDENTIFIED GLOBALLY AS ‘’;

GRANT CREATE SESSION TO sharedschema;

CREATE USER app_public IDENTIFIED BY abcd1234

DEFAULT TABLESPACE shared

TEMPORARY TABLESPACE TEMP;

GRANT CREATE SESSION TO app_public;

ALTER USER sharedschema

GRANT CONNECT THROUGH app_public

AUTHENTICATED USING DISTINGUISHED NAME;

Configuring the JDBC data source would leverage the app_public database user and any user that creates a proxy session would have visibility into the sharedschema data.