Showing posts with label 5minutesorless. Show all posts
Showing posts with label 5minutesorless. Show all posts

Wednesday, November 30, 2011

5 Minutes or Less: WLS SAML2 SSO and your cookies

This is somewhat related to what Brian describes in WLS Session Cookie Overriding in an OAM/SSO Enabled Environment. Here, I want to quickly point one potential issue if you plan to implement Web SSO using Weblogic server as a SAML2.0 Service Provider (SP).

When configuring a Weblogic server instance for SAML2.0 services, you have to fill in a property called “Published Site URL”.

ServiceProviderGeneralInfo


When this instance is an SP, this property tell the partner IdP (Identity Provider) where to post SAML Responses to. In the case of SAML2.0, that URL must be http://<server>:<port>/saml2, where <server> and <port> must refer to how the IdP recognizes the SP. In other words, if you have something like a load balancer in front of Weblogic server (which is the case if you’re running a cluster), <server> and <port> would be the load balancer’s. “saml2” is the web context of Weblogic’s internal SAML2.0 servlet, whose fully qualified name is com.bea.security.saml2.servlet.SAML2Servlet.

Very well, this servlet, when called as a Service Provider, has the ability to consume a SAML assertion created by the partner IdP and instantiate an HTTP session for the browser session in the server. And it will tie it to the browser session by issuing a cookie named JSESSIONID whose cookie-path is set to “/”.  So what?

It turns out that many applications specify their own cookie-path to avoid the problem of JSESSIONID clashing, where last accessed applications by the browser override the JSESSIONID cookie value during the same browser session, thus leaving orphaned HTTP sessions in the server.

It also turns out that other applications use a different cookie name to avoid the same problem.

In both cases, the JSESSIONID cookie issued by saml2 servlet won’t be accepted by the application. You may be prompted for authentication again (this time by the application), get an HTTP 401-Unauthorized error or get into an infinite loop of redirects between SP and IdP.

The most obvious solutions to these problems is removing the cookie-path constraint from the application (in which case it defaults to "/") and having the application using the JSESSIONID name. You may need to get the blessings of your application provider for supportability purposes before proceeding to the changes.

That said, get to know your applications' cookies (cookie-name and cookie-path) before integrating them into WLS SAML2 SSO.

Monday, October 31, 2011

Provisioning Users to Google Apps in Five Minutes

One exciting development (at least to me) in OIM 11.1.1.5 is the introduction of the Google Apps connector. Combine this with our existing SSO via Federation, it gives Oracle a nice lifecycle with Google Apps. Here is a quick primer on setting this up and a couple of gotchas on the docs. I wrote this a couple of months ago before the official announcement of the connector, so please correct me if there are any changes since.

There are a few 3rd party libraries from Google required for the connector. It appears that Google has updated its libraries already from what we’ve published in the doc. If you hit the problem described in http://code.google.com/p/googleappengine/issues/detail?id=3008, you probably have a “too current” version of the Google jars.

Here’s the documentation gotcha: In section 2.2.2, there is a note that states:

“Before you run the Connector Installer, you must ensure that all third party jars must be in targetsystems-lib/googleapps-11.1.1.5.0.”

The point that is intended here is that the folder structure must match the structure of the connector that is deployed. The distribution is “Google_Apps_11.1.1.5.0”, so if you take the docs literally and don’t change the name, things won’t line up. What is happening is that OIM is packaging the necessary 3rd party jars and importing them into the database. It’s important to get this right before installing the connector, or you get to go through a process of removing the jar from the database with scripts, repackaging, and re-importing.

Another confusing point is that the doc references the Java Connector Server. This might be a forthcoming solution, but for the time being, you can just substitute the OIM server anywhere it references the JCS. (This article didn’t have enough three letter acronyms (TLAs)).

Bottom line, what I think the packaging should be before the connector is deployed :

/Oracle_IAM1/server/ConnectorDefaultDirectory/Google_Apps_11.1.1.5.0/

/Oracle_IAM1/server/ConnectorDefaultDirectory/targetsystems-lib/Google_Apps_11.1.1.5.0/<3rd party jars>

/Oracle_IAM1/server/lib/<3rd party jars>

Deploying the connector from that point is standard fare. Here’s how I configured my IT Resource:


Once I assigned a resource and provisioned it, the user appeared in Google apps and I was able to SSO with that user via OIF immediately. I was also able to de-provision the user from Google by removing the resource entitlement from the user.

Friday, September 23, 2011

5 minutes or less: User/Role API and SSL

This short post follows up Couple of things you need to know about the User/Role API. Now imagine that your LDAP identity provider is SSL enabled in 1-way mode (the server authenticates to the client, but the client does not authenticate to the server).

Now you need to tell Weblogic server how to validate the LDAP server certificate. And this is accomplished by adding the LDAP server CA certificate to the configured Weblogic trust store. If we’re talking about a self-signed certificate, simply add the certificate itself to the trust store. And there are a couple of options for the trust key store: Command Line, Custom Trust, Java Standard Trust or the OOTB Demo Trust. So far, so good. By adding the certificate to one of these options, Weblogic is all good to talk to the identity provider in SSL mode.

However, the User/Role API is not directly tied to Weblogic, so don’t expect it to take whatever is configured for the server. By default, as a standard Java-based client, the User/Role API looks for the standard Java $JDK_HOME/jre/lib/security/cacerts file, unless you tell it to look elsewhere, by informing the java system properties

javax.net.ssl.trustStore=<path_to_trust_store_file>
javax.net.ssl.trustStorePassword=<trust_store_password>

Relying on the original cacerts file may be dangerous in case you upgrade your JDK. If you need to leverage the existing certificates there, make a copy of the file and use the copy. Then simply tell the User/Role API where to read it from using the properties mentioned above.

Thursday, September 22, 2011

Five Minutes or less: OpenID

Most of the technical people I work with know what SAML is and how it works and how the federation protocols for SAML work (SP initiated, IdP initiated, Browser Artifact, Browser POST). OpenID is much less well known.

So here's what you need to know about OpenID in five minutes or less.

In OpenID there are three parties:

  • The user and their browser.
  • The Relying Party (sometimes abbreviated to RP) is the web site that's asking the user to authenticate. In SAML this is the Service Provider.
  • The OpenID Provider (sometimes abbreviated OP) is the web site that's going to vouch for the user. In SAML this is the Identity Provider

Many people use the SAML and OpenID terms interchangeably when talking about the OpenID parties but I'll try to remember to stick with the right ones for this post.

OpenID works a whole lot like SAML's SP Initiated Browser POST authentication except for these differences:

  1. All user interactions are via HTTP GET
  2. The RP and OP communicate directly with each other via HTTP

Here's a simplified view of the flow:

I've broken the flow into three stages:

  1. Choose OP
  2. Login @OP
  3. AuthN
Note: these are my own divisions and names; the OpenID standard doesn't break the flow up and doesn't have names for what I call stages.

Stage 1: Choose OP
The first step in the OpenID flow is the user telling the Relying Party which OpenID Provider they would like to use, often though the NASCAR style row of buttons. Under the covers each of those buttons corresponds to a URL and when you click the button the HTML form is actually submitting the URL to the Relying Party's web site. In some cases the site will allow you to enter a URL of your choosing.

When you send the URL to the site the Relying Party checks to see if it "likes" the OpenID Provider (usually by checking against a list of providers). If the URL looks OK the RP makes an special HTTP request, called an XRDS request, to the OP. The OP returns back a bunch of data describing the OP including the features and functionality that the OP offers.

A couple of other things happen here, but in the interest of time I'm going to skip over them.

If everything looks OK the RP redirects the user to the OP with an Authentication Request (via an HTTP GET with the data in the query string).

Stage 2: Login @ OP
When the user sends their Authentication Request to the OP the OP makes the user login. If the user has already logged in to the OP then that step might be skipped.

After the user has authenticated to the OP the OP generates an authentication response for the RP and redirects the user back to the RP.

Stage 3: AuthN
Finally... the user presents that authentication response to the RP (via an HTTP GET). The RP checks it out and if it's "good" then the user is considered logged in.

Finally the RP returns the content, application or whatever it is that they were trying to do at the RP in the first place.

Monday, July 18, 2011

5 Minutes or less: Kerberos

Every time I talk to someone about Kerberos I need to take a few minutes to go through the concepts. This post is intended to just write down what I usually say and draw with a white board.

If you want to know more about Kerberos there's a metric ton of info out there on the internet. I'll leave it to you to go read up. For those of you that are experts on Kerberos please note that I'm going to simplify some stuff and gloss over a few important things; don't judge me for that - I'm just trying to make this all easy to understand!

A Kerberos Domain can be thought of as an island of single sign-on. Anything in the domain can authenticate securely to anything else in the domain without ever transmitting a clear text password over the network.

Everything in Kerberos is a Principal - machines, services and even users. A Principal is identified by a simple string called a Service Principal Name or SPN in one of two forms - either PROTOCOL/hostname for services (e.g. HTTP/www.mydomain.com for a web server) or username@DOMAIN for users (e.g. cjohnson@ATEAMDEMO.COM). The case of the string is important; the Protocol and domain name are always in CAPITAL LETTERS and the hostname and username are always in lower case.

There's a service on the network called a Key Distribution Center, abbreviated to KDC. The KDC has a list of every user and every service on the network and has a secret keys for each and every one of those Principals.

When a Service enrolls with the KDS the KDC generates a secret key for the service. That secret key is stored in two places - on the KDC and by the service (usually in a file).

When a user first logs in they use their password to the KDC prove their identity and get something called a Ticket Granting Ticket, abbreviated to TGT. Note that the password is never actually sent over the wire.

When a user wants to authenticate to a Service they go to the KDC and use their TGT to ask for a Service Ticket (ST) to talk to that service. The user asks for a ST for a particular service identified by the service's Service Principal Name (PROTOCOL/hostname). Note that, as usual, the user doesn't actually send the TGT to the KDC. Instead the client uses the TGT to prove its identity to the KDC, just as it did with the password.

In order to construct a Service Ticket the KDC takes the username, the service's SPN, a timestamp and a couple of other bits of information, puts them all together in a particular way and then encrypts that data with the Service's secret key and adds on some unencrypted data describing the ticket. Remember that only two things know that secret key - the KDC and the Service itself.

The KDC then securely returns the ST to the user.

Finally, the user sends their service ticket to the Service. To verify the Service Ticket the Service takes the encrypted ticket and tries to decrypt it using the secret key it got when it enrolled with the KDC. If the the ST decrypts correctly with that key then the service knows that the user was authenticated by the KDC; all the that remains is to check the timestamp and other information to make sure that the ticket isn't expired. If all of that checks out then the user is considered authenticated.

You'll note that the Service does not need to go to the KDC to verify the Service Ticket - all it needs is its Secret Key which it already has.

Here's a sequence diagram for you.

Remember when I said I was glossing over or simplifying a few things?

One of those things is how the Service gets its secret key. In my text above I said it gets that key when it "enrolls", but in the diagram I used the word "start" instead. That's one of those hand wavey places.

Another one is the TGT. A TGT is just a ST for the KDC itself. So if you look at a TGT you'll see that it's a special Service Ticket for krbtgt/DOMAIN.COM@DOMAIN.COM. For example here's mine:

Ticket cache: FILE:cjohnson.cache
Default principal: cjohnson@ATEAMDEMO.COM

Valid starting     Expires            Service principal
07/18/11 07:51:14  07/18/11 17:51:19  krbtgt/ATEAMDEMO.COM@ATEAMDEMO.COM
        renew until 07/19/11 07:51:14, Flags: RIA

Most of our posts here are pretty long and can take a while to digest. This one is intended to be read in 5 minutes or less. If you'd like to see more "5 minutes or less" posts please let us know in the comments below. If you DON'T want to see more of them please let us know that too.

Note: we may not publish the comments, but we promise to read them all.