This post is the first one of a series by Andre Correa and Paulo Pereira on OAG (Oracle API Gateway).
Throughout the series, we are going to talk about Kerberos authentication, Role Based Access Control (RBAC) and SAML identity propagation in OAG 11g, formerly known as OEG (Oracle Enterprise Gateway). What follows has been implemented as part of a larger exercise involving the SOA suite, OSB, OTD (Oracle Traffic Director) and the Exalogic platform. The kind of architecture presented here can be used as general guidance, but that may not apply to your use case scenarios. We will also briefly touch on OWSM policies that were applied to OSB and SOA composite.
The use case is about enabling end users to place orders. As you might think, there are quite a few 3rd-party systems to interact with in order to have the order fulfilled and the product provisioned to the end user. SOA to the rescue.
At the end of our exercise, the policy we built in OAG is expressed as the following circuit, where we can clearly see authentication, authorization and token switch. We expand the contents of each filter/policy as we go. In this post, we focus on the Kerberos Service filter and how we enable the policy for the service we want to protect.
Two 8-node clusters for OSB and SOA spread across compute nodes 3 an 4. One OAG group containing two gateways spread across compute nodes 1 and 2. OTD was employed as the load balancer between components.
A typical request flows as: client –> OTD –> OAG Group1 –> OTD –> OSB cluster –> OTD –> SOA cluster –> Stub server
Active Directory was deployed on Windows 2008 server platform.
Perhaps the most challenging part was the test client. Supporting Kerberos was a must. Our first and natural attempt was OAG’s API Explorer (formerly OEG Service Explorer). After numerous attempts, configuration changes everywhere, we came to the the conclusion that it simply does not support the SPNEGO protocol properly. In summary, it seems that it doesn’t honor the second leg of the protocol, i.e., after receiving a “WWW-Authenticate: Negotiate” HTTP header in the response, it does not resubmit the request along with the Kerberos token. And we also did not find a way to bypass SPNEGO and submit the Kerberos token directly. The free version of SOAP UI also failed.
Fortunately, via Prasad’s blog post, we came to know a .Net-based tool called WCFStorm-lite, dead simple, that just works. However, another requirement for this exercise was to show test automation best practices. So the client tool should ideally have scripts capabilities, allowing for the client integration into an ANT build script, for example. WCFStorm-lite has some scripts capabilities, but we did not go any further in looking at them, because almost at the same time we got to know Apache CXF’s support for Kerberos.
That basically put an end to our research. What could be better than simply writing a piece of java code? At the heart of Apache CXF’s framework are what they call interceptors, which are basically web services handlers. An inbound interceptor is attached to a web service and processes the message before service invocation. An outbound interceptor is attached to a web service proxy and process the message as it leaves the client. An out-of-the-box Kerberos interceptor interfaces with the KDC, gets a Kerberos token and attaches it to the request before sending it out to the web service (in our use case, a web service exposed by OAG).
We will get back to the client later on. First let’s concentrate on Kerberos configuration for OAG.
Kerberos is a temperamental beast. Understand it and treat it well, or it will bite you back. No wonder it is the 3-headed dog guarding the gates of underworld. It is a complex protocol, there’s a series of encrypted interactions between the client and the KDC before the client actually invokes the service. Debugging it can be a daunting and exhausting experience. There are tons and tons of Kerberos guides throughout the Net. I particularly like this self-explained diagram and the blog post of our colleague Chris Johnson.
1. Configure Active DirectoryYou must install Active Directory’s DNS so domain names are properly resolved.
Create Kerberos SPNs (Service Principal Names) for your users. You can do it in different ways, either using Windows’ keypass or setspn commands, as far as I know. An SPN has the format <SERVICE>/<USER_ID>@<DOMAIN_NAME>. Case matters. A good background on SPNs is found here.
Keep in mind that SPNs must also be created for the machines actually running the services. At the end of the day, the KDC grants the client a token to access a specific service. As part of the whole token session creation/exchange, the KDC has to know about the service. In our present case, our service is actually exposed via OTD (Oracle Traffic Director), who’s load balancing between two OAG instances. And make sure the OTD machine has a name (preferably, a fully qualified name). Kerberos does NOT get along with IP addresses. So, first create a user representing the OTD machine in AD and then issue it an SPN.
The command outputs a keytab file. Transfer this file to the 2 OAG machines. You’ll use this file when creating a Kerberos Service in OAG Policy Studio.
Repeat this for all users that are going to authenticate via Kerberos.
2. Configure OAG machine’s krb5.confOAG is going to validate the server name in the incoming service request against the SPN we are going to shortly configure for it (see following 2 subsections). For this very reason, we have to tell OAG which domain name we’re talking about and Kerberos server location. In OEL (Oracle Enterprise Linux), which is Ret Hat-based, edit /etc/krb5.conf, as per the following example.
3. Create a Kerberos Principal in OAG Policy Studio
The Principal Name field must be your server’s (who exposes services) SPN. In this present case, it’s OTD’s.
4. Create a Kerberos Service in OAG Policy Studio
Here you import the keytab file you got from Active Directory machine (use Load Keytab… button).
If the SPN here doesn’t match the server name in the incoming request, you’ll get a Kerberos checksum error.
If they match, but you don’t have the matching SPN in AD, you’ll get some sort of server not found error.
5. Create a new policy and add a Kerberos Service filter to itThis filter is the first one in our overall policy circuit (called Kerberos Authentication).
Notice the Kerberos Service field. It references the Kerberos Service created in the previous step.
That’s it. All other tabs are left untouched.
6. Register the target web service wsdl in OAG Policy Studio.
In WSDL URL, we actually entered the WSDL of the OSB proxy service load-balanced by OTD. Something like: http://exa7-vip1.osc.us.oracle.com:7101/echoprocessproxy?wsdl.
The screenshot below does NOT show the actual path used in our exercise. The important thing here is the hostname, which is OTD's.
This automatically creates a policy with a service handler filter.
Also, when registering the web service, Policy Studio asks you about the listener you want to deploy the service to. We've deployed ours to "Default Services" (listening on port 8080) and given it a path called "/echoprocess".
Clients can invoke it as http://<oag-server>:8080/echoprocess. Since in our exercise OTD is also front-ending OAG, clients actually invoke the service as http://exa7-vip7.osc.us.oracle.com:7201/echoprocess and OTD distributes requests between the two gateways. 7201 is obviously OTD's http listener port.
7. Add the Kerberos policy to Service HandlerDouble-click the Service Handler filter and add the Kerberos Authentication policy as the “Before Operation-specific Policy” in “Message Interception Points/Request from Client” tab. This will trigger our Kerberos policy before the web service invocation. All other tabs left untouched.
This is all as far as Kerberos configuration is concerned in OAG. We’ll discuss RBAC, SAML and the client in the following upcoming articles. Stay tuned.
Part 2: RBAC
Part 3: Getting a SAML Token and propagating it to OSB and SOA
Part 4: The Client