SAML Federation in OAM 11g R2



Oracle Access Manger 11G R2 adds SAML Relying Party support as a native feature. You no longer need to stand up and integrate OIF if you want to federate with another IdP.

SAML IdP support didn't quite make it into the first OAM R2 release - so you will still need OIF. This is on the roadmap - so stay tuned.

In this article I will show how easy it is to set up OAM as a SAML relying party.

I am using OIF configured as the sample IdP. See my previous article on setting up OIF to self federate (handy for experimenting). Assuming you have OIF configured you should be able to bring up the test SP SSO page:  http://demo:7499/fed/user/testspsso


You will be challenged for credentials. After logging in you will see this:




Great. Now we have a working IdP we can proceed to setting up OAM as a relying party.

As a pre-requisite make sure you have federation services enabled in OAM 11G (System Configuration -> Available Services)

Bring up the OAM Console and navigate to System Configuration -> Identity Federation

Click on “Identity Providers” and select the new icon.







Next we need to load the SAML IdP meta data from OIF. You can export it from the em console or bring up and save this URL:

http://demo:7499/fed/idp/metadata

Select and i
mport this meta data file into OAM. You should also select “Create Authentication Scheme and Module” at this time. Save your changes. You now have OAM configured as a Relying Party.


We still need to configure OIF to know about OAM as the service provider. To do this, export OAM’s SP meta data (under Federation Settings), and import it into OIF (Admin -> Federations ):







Edit the new federation in OIF:

In the edit screen click on the Enable Attributes in Single Sign-on.

  • Click “X509 Subject Name” and “Email Address” checkboxes and click Apply button.
  • Then click on Edit button next to the “Attribute Mapping and Filters”.
  • In Name mapping tab – add two mappings
    • User Attribute Name – givename Assertion Name givenname
    • User Attribute Name – title Assertion Name role
Make sure “Send With SSO Assertion” is enabled.

Back in OAM, navigate to Policy -> Authentication Schemes. You will see a new Authentication Scheme has been created:





You can use this Authentication Scheme in a policy - just like any other (LDAP, Kerberos, etc.).

To test your federation, create a test directory under your ohs1 instance and protect this URL with the federation Authentication Scheme. The OHS folder is something like:

/app/oracle/fmw/Oracle_WT1/instances/instance1/config/OHS/ohs1/htdocs

For this example we have created federation/index.html file under htdocs.

Bring up the policy domain for ohs1, and create an Authentication Policy that use the Federation Scheme:







Now create a resource and protect it with the policy:







Clear your browsers cookies and bring up the URL:

http://demo:7777/federation/index.html


Because this URL is protected by the Federation Scheme, OAM will initiate federation with the configured IdP. You should see the IdP logon page. After log on you will be re-directed back to the protected page.


Pro Tip: Install the SAML tracer firefox plugin so you can watch the SAML message exchange!




OAM R2 REST APIs for Policy Management



Oracle Access Manager 11g R2 provides several new REST APIs. This continues a trend to expose key functionality via Web Services.

The OAM Mobile and Social service provides APIs for Authentication, Authorization  and User Profile services.  I will cover those APIs in a future article (have a look here for examples) - but today I want to focus on the  policy management APIs.

The Policy Administration API enables to you to interact with OAM to create a variety of Policy objects such as Application Domains, Resources, AuthN Schemes, and AuthN/AuthZ policies. The policy model is shown below:




For example, if you want to retrieve all of the resources in an Application Domain you can perform a GET against the /resource URI:


curl -u USER:PASSWORD http://<SERVER>:<PORT>/oam/services/rest/11.1.2.0.0/ssa/policyadmin/resource?appdomain="IAM Suite"

Note: The port above is where the OAM Admin Server is deployed (often 7001). It is NOT the managed server (oam_server1 - 14100 by default). 

These APIs are useful for anyone who wants to automate policy creation. To provide an example: Let's assume we want to automate the process of bringing new applications online. Each application will have a resource URL to protect (example: /financeapp/**) and an LDAP group which should be used to enforce access to the application (example: FinanceManagers).

To demonstrate this functionality I have created a small Netbeans project that you can download here.

The demo uses the Jersey client to invoke OAM's policy management API.

The XML schema is used to generate JAXB bindings for the various policy objects.  This schema can be found in your deployment directory for OAM (perform a find ..../domains/IAM -name *.xsd -print) to locate it. A copy of the schema is included in the project file - but this may change with subsequent releases.

The demo does not cover every use case - but it should give you the general idea. Feedback is welcome!






Subject to change – JAAS to JASPI

The move from JAAS to JASPI subtly changes how we interact with identities. In the world of JAAS we deal with Subjects who are the entities making a request, typically a user, whilst Java EE deals with Principals, the representation of that entity such as a username. The difference may not seem great, but a Subject may have several Principals and this has caused some headaches when using JAAS, leaving determination of the relevant Principal to the implementation.

The days of JAAS have long been numbered however, and JSR-196 (also known as JASPI or JASPIC) is emerging at last; inclusion in JEE6 has definitely helped to push JASPI beyond just Glassfish support.

One of the changes is using the CallerPrincipalCallback to present to the container which Principal is applicable; and which is then available in the ServletRequest using getUserPrincipal(…).

Some background music for mulling over Subjects and Principals: Subject’s theme from Aldo Nova

Stupid Oracle vktm tricks to improve VirtualBox performance



In the process of creating a demo VirtualBox image running OEL 6 and the Oracle database 11.2.0.3.0 I noticed the idle CPU consumption was quite high (8% on the guest, 35% on the host).

The culprit turned out to be the Oracle database vktm process. This is a time keeping process - and it calls gettimeofday() *very* frequently.  This can have a negative performance impact in virtualized environments.

A colleague who is a database whiz suggested the following trick:


sqlplus / as sysdba
alter system set "_high_priority_processes"='LMS*' scope=spfile; 

This removes the vktm process from the list of high priority processes.

After this change (you need to bounce the database) the idle CPU consumption comes down to 1-2% or so. A nice improvement!

It goes without saying that this is:

a) Totally unsupported
b) Probably dangerous. This will most certainly break things in the database - such as statistics, auditing, etc.
c) For demo/development use only. If you care about your data don't do this!

YMMV.


Getting bitten by SELinux and sshd authorized_keys




TL;DR:  If you can't ssh using a public key, it could be a SELinux thing.


Logging in to a server with ssh using your public key is pretty handy.  While setting up an OEL 6 VM  I ran into a strange error where sshd would not let me log in with a public key, even though my key was in ~oracle/.ssh/authorized_keys.  Password logins worked just fine.

Somewhat puzzling: I could ssh into the root account using my public key and without a password.

Nine times out of ten, this is a permission problem. Sshd is picky about the permissions on your home directory, ~/.ssh, and the authorized_keys file.  I carefully checked this over - but in this instance permissions were not the problem.

The standard advice to debug SSH problems is to run sshd in the foreground with debugging turned on:

service sshd stop
/usr/sbin/sshd -dD

And of course my problem promptly disappeared. Hmmm, so it works in debug mode, but not when running as a daemon. It also works fine to ssh into the root account, but not ~oracle.

My initial google-fu skills were weak, but on a hunch I googled "sshd SELinux".

Bingo:

http://serverfault.com/questions/50573/selinux-preventing-passwordless-ssh-login


In my case disabling SELinux did the trick (not good for production, but acceptable for my purposes).



Oracle Identity Federation: Federate yourself!


A customer asked me how they could test their OIF IdP configuration without standing up another relying party.

Since OIF can act in both roles (IdP and SP), in turns out you can configure OIF to federate against itself.  It's seems somewhat crazy, and its not all that intuitive, so I thought I would include a few notes on how to set this up.

The key is that you must export OIFs SP and IdP metadata and re-import it back into OIF as configured federations. The "/fed/user/testspsso" test page can be then be used to initiate the federation.

Here are the basics of how to accomplish this.

Step 1: Export your SP and IdP metadata. This is done from the em console.
Administration -> Security and Trust:





Step 2) Import the exported meta data back into OIF:
Administration->Federations 

Click on the "Choose File" button and select the meta-data files you exported in step 1




You should now have an IdP and SP configured under your federations.  You may want to edit your federation settings to enable additional attributes to be mapped or change the default request format (POST, for example). See your OIF Admin guide for the details.


Step 3) Set your default SSO Identity Provider to be the newly created IdP that you just imported.

Administration->Service Provider->Common






Step 4) You are now ready to test your IdP

There is a neat Firefox plugin called "SAML Tracer" that is great for debugging SAML isses.  I highly recommend installing it.

Navigate to the test SP SSO page. This is located at:
 http://your-oif-server:7499/fed/user/testspsso

You should see something like this:




Click on "Start SSO".

You will be redirected to your OIF login page. Assuming you have configured LDAP authentication (Administration->Auth Engines -> LDAP), you will see this:


Login with your LDAP credentials, and you will see the response from the IdP:





If you are using the SAML tracer you can see the SAML request (OIF acting the SP role) and the response (OIF acting in the IdP role).  Here is an example request:









Congratulations. You have now federated with yourself!




How to use Certificate module with DAS

Previously I have described how to install the DAS properly. Today’s entry is all about using the Certificate authentication module in a deployment where you have a DAS instance. So here are the steps required to make this work:

  • Follow the DAS install guide, but with the only difference being that you install the DAS on a HTTPS URL (OpenAM can keep running on HTTP). Since you are now using HTTPS, you need to make sure that the OpenAM server trusts the DAS’s certificate, otherwise OpenAM won’t be able to send notifications to the DAS, which could result in strange situations when a given session remains valid for a short period of time even though the user has logged out on a different DAS instance.
  • Go to Access Control – realm – Authentication page and Add a new Module Instance called cert with type Certificate
  • Open the Certificate module configuration, and change the followings:
    • Set the LDAP Server Authentication User/Password to correct values
    • For evaluation purposes set the Trusted Remote Hosts to “all”
  • Generate a new self signed certificate by following this guide, but make sure that in the CSR you set the CN to “demo”.
  • Create PKCS#12 keystore for the freshly generated private key and certificate:
    openssl pkcs12 -export -inkey server.key.org -in server.crt -out server.p12
  • Install the PKCS#12 keystore in your browser (Guide for Firefox)
  • Enable Client Authentication on the DAS’s container. For example on GlassFish 3.1.2 Admin Console you would have to go to Configurationsserver-configHTTP serviceHttp Listenershttp-listener-2 then open the SSL tab and check the Client Authentication option.
  • Install the public certificate into the container’s truststore, so the container will actually trust your certificate:
    keytool -import -keystore glassfish3/glassfish/domains/domain2/config/cacerts.jks -file server.crt -alias mycert

    You need to make sure that you install the certificate to the actually used truststore, some containers may use the JVM’s truststore instead having one on their own.

  • On the DAS enable the Request/Response serialization by setting the following property in the ~/FAMDistAuth/*.properties file:
    openam.remoteauth.include.reqres=true
  • Restart the DAS’s container
  • Open /auth/UI/Login?module=cert and choose your certificate
  • Profit

Some useful shell scripts for setting up Oracle Linux



Do you frequently need to setup new instances of Oracle Linux to host the database, Weblogic, and  IAM Middleware?

I nabbed some great scripts from my colleagues Chris Johnson (of Fusion Security fame) and Art Mattson. I threw in a couple of my own scripts (great artists steal, right?), and have assembled these as a github project.

If you are setting up a new system grab the scripts with:

wget https://github.com/wstrange/Oracle-IAM-Scripts/zipball/master

Standard disclaimer: These scripts come with no warranty. Use at your own risk!

If you have some useful scripts that you would like to contribute drop me a line.

Integrating Oracle Identity Federation (OIF) with Service-Now



Oracle Identity Federation (OIF) provides SAML and OpenId federation services. OIF helps organizations to leverage SAAS  as part of their IT strategy by providing identity federation.

As part of  a recent POC we completed an OIF integration with Service-Now,  a cloud base IT Service management platform.

John Andersen is a rock star consultant from Service-Now who worked with me on the integration. We have documented the procedure and included a few screen shots (see link below).  Your environment will be a little different - but this recipe should get you going. Comments or corrections  are welcome!

Reference:  Configuring OIF and Service-Now


A Custom OIF Authentication Engine



Oracle Identity Federation (OIF) provides a flexible architecture that enables new authentication engines to be plugged in to the IdP flow.

There are a number of standard Authentication Engines that come out of the box such as Oracle Access Manager (OAM), LDAP and Oracle SSO (OSSO). Most deployments will use the OAM integration, but there are some scenarios where another mechanism is desired.

This posting will show you how to create and configure a custom authentication engine for OIF. In this example we will demonstrate the engine calling out to a simple web service that implements the authentication logic.

Authentication Flow

The authentication flow for our custom auth module is shown below.


















Recall the Fedlet from our previous article, which is a light weight SAML relying party implementation. The interesting bits here are the CustomAuth engine and the WebService that  implements our authentication logic.

Project Sample Code

The sample code for this project can be viewed and downloaded at https://github.com/wstrange/OIFAuthEngineDemo

The AuthSvc/ folder contains our authentication web service. The relevant snippet is


    @WebMethod(operationName = "authenticate")
public AuthInfo authenticate(@WebParam(name = "userid") String userid,
@WebParam(name = "password") String password) {

AuthInfo a = new AuthInfo();

if (userid != null && userid.startsWith("test")) {
a.setZipcode("12345");
a.setStatus("OK");
a.setSubscriberid(userid + "1234");
return a;
}
a.setStatus("ERROR-Auth");
return a;
}

This is a simple web service that authenticates any user whose id starts with "test" (no multi factor here!).  We  return an AuthInfo object that contains attributes for OIF to insert into the SAML assertion for a partner. Don't worry about the details of this web service - it is purely illustrative.

Under the engine/ folder for the project you will find the relevant jsp files for OIF integration. These jsp files are the entry hooks that OIF will call out to during user session creation. They must be deployed in the same container that OIF is running on as Servlet forwarding is used to pass data in and out your custom auth engine.

The integration hooks are documented in the OIF Admin guide.  The provided examples should get you bootstrapped.

loginpage.jsp is where the action gets started. This jsp is responsible for displaying the credential collection dialog to the user before forwarding control back to OIF.

Next, OIF will call out to the next JSP in the chain: forward.jsp. This jsp invokes our sample web service to authenticate the user. If authentication succeeds, the attributes returned from the web service are put in the SSO session. OIF will pick these up and add them to our SAML assertion for our partner.  If the authentication fails we redirect the user back to OIF where the login page will be tried again.

Here is the relevant java code from forward.jsp:

String refid = request.getParameter("refid");
String authnMethod = "oracle:fed:authentication:password-protected";
String userID = request.getParameter("username");
String password = request.getParameter("password");
// you get this id from OIF->AuthEngine->Custom page
String TEST_ENGINE_ID = "8172C8E5A7";
Date now = new Date();

AuthSvc_Service authsvc = new AuthSvc_Service();
AuthSvc svc = authsvc.getAuthSvcPort();
AuthInfo info = svc.authenticate(userID,password);

if( info == null || info.getStatus().startsWith("ERROR") )
{
String message = info.getStatus();

String redirectURL = "/engine/loginpage.jsp?refid=" +
(refid != null ? URLEncoder.encode(refid) : "") +
"&message=" + URLEncoder.encode(message);
response.sendRedirect(redirectURL);
return;
}

Map attrs = new HashMap(); // Attribute map to put in the SSO sesion
// Attributes from the sample web service
attrs.put("zipcode", info.getZipcode() );
attrs.put("subscriberid", info.getSubscriberid() );
// You can also pass back multi-valued attributes
HashSet s = new HashSet();
s.add("Bill");
s.add("Sue");
attrs.put("children", s);

request.setAttribute("oracle.security.fed.authn.attributes", attrs);
request.setAttribute("oracle.security.fed.authn.engineid", TEST_ENGINE_ID);
request.setAttribute("oracle.security.fed.authn.userid", userID);
request.setAttribute("oracle.security.fed.authn.refid", refid);
request.setAttribute("oracle.security.fed.authn.authnmech", authnMethod);
request.setAttribute("oracle.security.fed.authn.authntime", now);
request.getSession().getServletContext().getContext("/fed").
getRequestDispatcher("/user/loginsso").forward(request, response);

The final piece of the puzzle is the logout hook.  logout.jsp simply tells OIF to terminate the SSO session for the user.

The above jsp are packaged up into a war file, and must be deployed to the same Weblogic instance that is running OIF (wls_oif1, for example). Note this is *NOT* the admin server instance.

A tip: While debugging your engine deploy this as an "exploded war" file and enable hot jsp reload. This will allow you to edit your engine without bouncing the app server.

Configuring OIF 

Log on to the OIF console (http://localhost:7001/em for example), and navigate to
Administration->Authentication Engines

Click on the "Custom Authentication Engines" tab, and click on "+" to create a new engine. This is where we define our integration points.  Here is a sample:



Note the Engine ID column. This generated unique ID must be used in your forward.jsp to identify the engine to OIF.

Once you have defined your Authentication Engine remember to set it as the default engine.

Finally you will want to update the federation definition for you partner to pass back the desired attributes in the SAML assertion.  Navigate to Administration -> Federations , select your partner and click edit.

Click on "Attribute Mapping and Filters". This is what my example looks like:



Recall that the "zipcode" attribute was passed back from our web service and placed into the OIF session by forward.jsp.  This attribute is being made available to our partner in the SAML assertion where it will be called "zipcode".

If you have a user data store defined in OIF you may also pull additional attributes for the  user. The user id that authenticated will be correlated to a user in the data store. This is not a requirement (you can set the datastore to "None").

You are now ready to test your custom authentication engine using the Fedlet.  If you run into problems have a look at the OIF instance logs. Errors in your forward.jsp will usually show up as exceptions in this log.