Showing posts with label identityasserter. Show all posts
Showing posts with label identityasserter. Show all posts

Tuesday, November 8, 2011

Why do I need an Authenticator when I have an Identity Asserter?

Another common question on the internal mailing list:
Why do we need an OID authenticator when I have the OAM Asserter enabled? The user has already been authenticated when the request gets to WebLogic.
The short answer is that all an Identity Asserter does is says "the request is authenticated and the username is Chris". WebLogic then needs to know how to find "Chris" and to do that it needs an Authenticator.

The longer answer is available on the net already... it's just a matter of finding it.

The old O'Reilly WebLogic book says

Identity Assertion Providers help secure access to the entry points of a WebLogic deployment. Instead of using usernames and passwords, an external client may use tokens to establish trust with a WebLogic Server. The Identity Assertion Provider verifies a token and, if successful, maps it to a valid WebLogic user. Once the token is mapped to a valid user, an Authentication Provider can then generate the principals for the user. This mechanism is called perimeter authentication, so you can consider an Identity Assertion Provider a special type of Authentication Provider. The key point here is that an external agent is responsible for authenticating the user, and then for conveying the user data to WebLogic.
Robert's Professional WebLogic Server book says
This security provider maps an outside authentication token to a username. This allows for functions like perimeter authentication. The identity asserter provides an implementation of a JAAS CallbackHandler. The default identity asserter supports WebLogic Server security tokens, X.509 certificates, CSIv2, and WS-Security password digest.

Without an Authenticator that can find the user there's no way for WebLogic to create the Subject and Principals.

I wasn't going to include this, but there is a little fine print: Identity Asserters can assert the identity without an Authenticator. These are pretty rare so let's leave that for a different post.

Tuesday, August 17, 2010

Kerberos and WebLogic Server - decisions, decisions

I've been away from the blog for a while - I took some vacation time and I've been working on a customer that I can't really talk about. Have you missed me?

No? I didn't think so.


I got a call yesterday asking me to help a customer trying to get SPNEGO/Kerberos working between Windows desktops and WebLogic server. Yes, Kerberos again. After talking through what they're trying to accomplish today I found that they may have started out on the wrong foot to begin with.

Here's (more or less) what they told me they're trying to accomplish:
We have an app deployed in WebLogic and we want users that are in the domain to be able to access that app without being prompted for credentials.
That's it.

There are three ways that I can think of right away to address that requirement:
  1. Use WebLogic's SPNEGO Identity Asserter to have WebLogic verify the Kerberos ticket
  2. Use IIS to do the Kerberos bits and then use a simple HTTP header Identity Asserter to get the identity into WebLogic
  3. Use Oracle Access Manager
Each of the solutions have their own plusses and minuses. The point of this post is to try to get them written down to help you (or someone else) make a sensible decision about which one to pick.

Before I get into it let me just say that Kerberos/SPNEGO is one of those technologies that when it works it's awesome, and when it doesn't it's incredibly frustrating to figure out what's gone wrong. Add to the mix the fact that so much of what's happening is automatic and so few people actually understand what's really happening under the covers/on the wire and you have a recipe for pain, frustration, annoyance and lots of hair being pulled out.

With that said...

WLS + SPNEGO Identity Asserter
WebLogic includes an the necessary bits that allow WebLogic to verify a Kerberos ticket if you want. I've blogged about it before and there are official docs as well as oodles of threads on Oracle forums where people are struggling to get it working. It definitely works and it has gotten easier over the years, but it's still harder than flipping a switch and being done.

The requirements basically amount to getting a Kerberos service principal registered, getting the necessary secret key onto the box running WebLogic and then getting WebLogic and IE to agree to do SPNEGO. Each of those steps is manual and it's easy to make a mistake.

Plusses: baked into WebLogic so there are no dependencies on any other software, Kerberos ticket is verified inside WebLogic itself and is thus about as secure as possible.
Minuses: can be difficult to setup & troubleshoot

Use IIS to do the hard stuff

One of the great things about Microsoft embracing Kerberos is that some very difficult, very complicated things have been reduced to a checkbox. To enable Kerberos in IIS you add the web server to the domain, then you go into the IIS console, edit the Security properties of a directory or of the server and check one box - "Integrated Windows Authentication". Windows and IIS do all the hard stuff for you including setting up the Kerberos principal.

Yes, I'm glossing over a few things, but not many.

Once you've got IE and IIS doing the Kerberos/SPNEGO dance two things remain: (1) getting IIS to proxy requests over to WebLogic and (2) getting WebLogic to trust IIS' say so on the user's identity. The former is address by the IIS WebLogic Plug-in. The latter is a simple Identity Asserter like the one I discussed back in January (I really need to put that code up somewhere on the Internets!).

Plusses: One checkbox to enable Kerberos in IIS
Minuses: You have to deploy Windows & IIS in front of every WebLogic server. The security issues I mention in my older post

Use OAM

OAM provides two relevant things - SSO across web sites and access control to those web sites. The former is all we're interested in here; when a user accesses the web server OAM will detect that they haven't authenticated yet and kick them into a process to do that. The latter allows you to decide who gets access to what parts of the protected web sites; it's not something we care about in this case but it can be very useful.

The upside to using OAM in this case is that you only need one or two IIS web servers somewhere in your environment to get Kerberos working. Each of the OAM WebGates plugged into your protected web servers will redirect users to one of those machines to figure out who the user is and then back to the protected web server. This works regardless of which flavor of web server you use - OHS, Apache, IIS, or Sun One. I've seen customers do this sort of thing with as little as one IIS server, but for redundancy you want a pair of IIS boxes somewhere in your environment and probably a second pair in a disaster recovery environment as well.

Plusses: Few Windows/IIS servers needed.
Minuses: Requires additional software (OAM WebGate) to be installed


In this particular customer's case they'd tried the first option already and had run into some issues. Because of those issues and because their requirements were still in flux I suggested that they try the second option (IIS doing Kerberos along with a username Identity Asserter). Your mileage may vary and you should probably ask a knowledgable person for advice before picking one of these options, but that's (part of) what we're here for.

I'm interested in what you think. Let me know in the comments!

Wednesday, April 7, 2010

Security Clarification: OAM Identity Asserter for WebLogic

I want to clarify something rather important about the Oracle Access Manager (OAM) identity asserter for WebLogic. The OAM identity asserter is invoked based on the token "OBSSO Cookie" (though I think it now also lets you choose "OAM_REMOTE_USER"). It also contains provider specific configuration for connecting to an OAM access server. This might lead you to conclude that the identity asserter is validating the OBSSO cookie and then asserting the name extracted from the cookie.

The reality though is that even when the OBSSO cookie is the configured token for invoking the identity asserter, the asserter itself is simply asserting the value of the OAM_REMOTE_USER header. So, what about all the configuration for the connection to the access gate? The access gate connection only comes into play in an OAM/OWSM integration scenario where there is no webgate on a web server in front of WLS. If you are using the identity asserter to propagate an identity to an OAM protected web app then you don’t even need to fill in all that info.

If you had the wrong impression, don’t feel too bad. It is an easy and common mistake to make. The documentation touches on this here as step 2 is about establishing trust with WLS, but glosses over it in its description (10.2.2.2) of how the identity asserter works, which is why I thought this blog post was necessary.

So, given that the OAM identity asserter is asserting an identity contained in a clear text header that is inserted into the request at the web server, it is vitally important that measures are taken to ensure that all requests to OAM protected WLS resources come through the OAM webgate enabled web server.

As Chris mentioned in his post a few weeks ago this can be done by:
  1. Taking network security measures.
  2. Two-way SSL.
  3. Utilizing the WLS connection filter to lock down what IP addresses WLS will service requests from.

Thursday, April 1, 2010

SAML, REST, smart phones and you

(or Smart devices, not so smart protocols)

I've been working on and off with a customer on a project that involves all sorts of cool buzzwords - iPhone/Android/Blackberry Apps as clients, using REST to invoke Web Services, authenticating via SAML. While I can't go into the details or reveal too much about the project there is one line of discussion that is really interesting.

First the background:
  1. A thick client, running on a smartphone, will do some sort of handshake with one web server to authenticate the user.
  2. Once the user is authenticated that server will issue the user a SAML Assertion.
  3. The client will then use the SAML assertion to authenticate to a different server and will send REST-style requests to invoke services on that server.
So something like this:



This begs the question why not just use a conventional web SSO product like Oracle Access Manager? An excellent question, the short version of which is that the Authentication Server and the REST Server are run by two different companies and don't share any infrastructure (a more common situation than you might think).

SAML actually solves a whole bunch of painful problems in this architecture - the AuthN server can sign the SAML Assertion to prove its validity and protect it from alteration and encrypt it to prevent the user from even seeing its contents. SAML also allows the AuthN server to send additional information about the user (i.e. attributes) in an extensible way - and additional attributes can be added later without needing to change any infrastructure, communication protocols or even the client.

Did you fill up your Buzzword bingo card yet?

So moving on to the problems...

Transmitting the SAML Assertion
If we were using SOAP to go from the device to the server WS-Security would have solved all of our problems. That standard spells out exactly how to attach a SAML assertion to a SOAP message so that both the client and server can understand. Unfortunately almost all "smart" devices lack a full SOAP stack. Further complicating matters is the fact that REST is a (air quote) "standard" intended to be a very lightweight way to send requests to a server and get back a structured response. Because it's intended to be so much simpler than SOAP there's very little (read no) standards around things like authentication, encryption, signing or any of the things that make SOAP a bit complicated at times.

All of which is just a long way to say that you're basically on your own figuring out how to use SAML with REST.

There are a few obvious options of how to use SAML with REST.
  1. Send the SAML assertion to the server and swap it for a cookie. Your deployment then becomes nothing more than a standard web SSO situation and your application doesn't need to worry about the SAML bits.
  2. Send the SAML assertion in every request as part of the POST data. This places the responsibility for parsing the SAML assertion into your application logic or something that can see and handle the HTTP POST data stream.
  3. Send the SAML assertion in every request as an HTTP header. This is a slight variant of #2 that is more similar to SOAP's WS-Security model where the authentication information is separated from the actual input/output parameters of the call.
I like option 1 because it pushes handling the SAML assertion out of scope, or in other words into an S.E.P. On the other hand having a thick client interacting and cooperating with a web SSO solution introduces a whole raft of other issues including properly handling things like idle and session timeouts, dealing with redirects, and a long list of others. Web SSO products were designed to interact with web browsers and their 'on the wire' behavior can be difficult to understand from an HTTP client's perspective. I'm not convinced that this is the best solution to our problem so on to options 2 and 3.

Option 2 and 3 are nearly identical - differing only in where the assertion goes in the HTTP request. That subtle difference is actually kinda a big deal and after thinking about it for a while I think I vastly prefer option 3 to option 2. Besides the logical separation of authentication and inputs I have a few other reasons, such as the fact that POST data can only generally be consumed once which is really important for my next trick.

You probably know about Servlet Filters, and if you've been reading this blog for a while you probably know about WebLogic's security framework (often called the SSPI framework). What you may not know about is how to put them together into a Servlet Authentication Filter. Basically you write a Servlet Filter that takes on responsibility for getting the authentication token and then ask WebLogic to go call the authentication provider for you. If everything works out WebLogic goes ahead and establishes a session for you. Then when your actual service wants to know who is invoking the service it can ask by calling weblogic.security.Security.getCurrentSubject().

No fuss no muss. And most importantly you don't have to commingle service logic with any code to deal with SAML, encryption keys, XML parsing or anything else unrelated to actually doing your actual work!

Session Management
One of the concerns with sending the SAML assertion along with every request is the performance impact of the XML and crypto operations. If you are invoking a simple service (hello world for example) the overhead of all of the SAML seems like it might be awfully expensive. If you had to pay that price with every request the overhead would quickly eat up your CPU cycles grinding even a reasonably fast machine to a halt under load.

Thankfully WebLogic's designers thought about this very problem.

The first and most obvious solution is to act just a little bit more like a browser. When you authenticate to Weblogic it automatically creates a session for you and sends a cookie (usually named JSESSIONID) back to your browser. If you include that cookie with subsequent requests there's no need to authenticate again. So if you smarten up the client so that it handles cookies gracefully you'll avoid WebLogic having to re-parse and validate your SAML assertion. In fact if I'm reading the relevant iPhone SDK docs (just to cite one example) correctly I think the iPhone SDK handles cookies properly for you automatically by default! Android includes Apache HttpClient which makes cookie handling almost trivial. And as for Blackberry, well it's J2ME which means you'll have to do cookie parsing by hand; which, while unfortunate, isn't the end of the world.

As long as you do the right thing with the cookies coming from WebLogic your session will be fine. If something happens to your session (e.g. the server gets rebooted, you get shunted off to another server that doesn't know about your session, your session times out, etc) the auth filter will automatically reestablish a session as long as your SAML assertion is still OK.

But that's only one part of the solution. If you disable WebLogic's issuance of cookies or you choose to not handle cookies in your thick client's code WebLogic has still got your back.

Weblogic's Identity Assertion Cache
Decrypting a chunk of XML, parsing it, and extracting some data takes some CPU cycles, but isn't all that slow. Searching an LDAP directory to find a user, then doing another search to chase down all of the group memberships on the other hand takes real, measurable clock time. Some of the time is because you're doing a search and some is because you're going over a physical wire to talk to the LDAP server and those wires (AFAIK) are still subject to the laws of physics.

The WebLogic docs describe the setting in some detail. The Javadoc for the Authentication Provider says:
The assertIdentity() method of an Identity Assertion provider is called every time identity assertion occurs, but the LoginModules may not be called if the Subject is cached. The -Dweblogic.security.identityAssertionTTL flag can be used to affect this behavior (for example, to modify the default TTL of 5 minutes or to disable the cache by setting the flag to -1).
And the command line reference fills in some more details:
When using an Identity Assertion provider (either for an X.509 certificate or some other type of token), Subjects are cached within the server. This greatly enhances performance for servlets and EJB methods with tags as well as for other places where identity assertion is used but not cached (for example, signing and encrypting XML documents). There might be some cases where this caching violates the desired semantics.
Wrapping it all up
So to summarize:
  • SAML is cool
  • smart devices are pretty cool, but they lack a SOAP stack
  • WebLogic's SSPI framework is cool
  • the WebLogic engineering team thought of darn near everything
Oh, and if you combine a Servlet Auth Filter, the SAML SSPI Identity Asserter, a teensy bit of code to handle cookies on the client side you can do some pretty clever things.

Got a comment or question? Let me know below!
----
Update: After having this up a few days I had a talk with someone out of band that in effect said "you said #1 is probably not the best way, but then you went through a whole discussion about 2/3 but wound up describing #1 and saying that it was best." So I obviously need to clarify.

What I was talking about in #1 is actually invoking a specific server. In other words login(String SamlAssertion) and have a token come back. The problem with that solution is that it's complicated and if the token isn't acceptable for some reason you need to know how to go back and get a fresh token.

In the rest of the post I describe sending the SAML Assertion on every request and doing "the right thing" when it comes to cookies. If the server sees the cookies and can find the associated session it won't bother checking the SAML assertion. If you don't have a cookie, the cookie or session is invalid or something else goes wrong then the server will go ahead and validate the SAML Assertion and establish a new one.

Hope that clears things up.

Friday, January 22, 2010

The Worlds Most Dangerous WebLogic Identity Asserter

...or how Josh stole my idea for a post in one paragraph.

In a recent post Josh said
There is another approach that, unfortunately, is rather common - use a Web Gate in front of WebLogic Server and use a very weak identity asserter or no SSPI connector at all.


I'd started writing this post before Josh wrote that and figured I'd post this anyway in hopes that my longer and more detailed write up is helpful to someone unfamiliar with what all of the terms and acronyms mean.

WebLogic Server includes a great security framework that provides five services - authentication, role mapping, authorization, auditing, credential mapping. There's also a sixth service called adjudication that kicks in if you have more than one authorization provider, but that's a story for another day. Out of the box WebLogic ships with a bunch of providers for each of those services.

The authentication service/interface does exactly what you'd think - takes a set of credentials, verifies them, and allows WebLogic to create a JAAS subject and principals for the user. Out of the box credentials are things like username and password against an LDAP directory. The ability to assert a user's identity without having their actual password, for example via a certificate, is also supported; in that case the authenticator is called an Identity Asserter.

So what is the worlds most dangerous identity asserter?

To answer that you have to understand the typical WebLogic deployment architecture. The recommended way to deploy WebLogic is to deploy a load balancer, two or more web servers (Apache, OHS, IIS) with the WebLogic plug-in, and then two or more WebLogic servers. Here's a diagram:

This architecture allows you to do a bunch of very useful things - gracefully handling single component failure, load balance across the components, scale up more or less linearly by adding additional WLS servers, and more.

Enterprise deployments also typically involve integrating with web single sign-on solutions like Oracle Access Manager (OAM), SiteMinder, or even Microsoft's Kerberos implementation included in Windows.

When you do the authentication at the web tier you need to convey the user's identity over to WebLogic and install in an Identity Asserter to populate the JAAS subject and principals. When you're doing authentication on the web server the most obvious way to write an Identity Asserter is to just consume the username HTTP header - after all the web server already did the authentication why bother doing anything more?

Why? Because if anyone manages to sneak by your web server they can impersonate any user in your user directory. Combine that with the commonly quoted statistic that two-thirds of security breaches are internal rather than from a hacker on the outside.

Let the implications of that sink in for a second...

Assuming you did everything else right in your app and environment your biggest risk is a bad guy inside your network. If you write an Identity Asserter that just blindly trusts an HTTP header you'd better be sure to do something to protect the WebLogic server.

I recently encountered a customer that wanted to authenticate their users with Kerberos authentication at IIS rather than inside WebLogic. They could have done the authentication in WebLogic with the SPNEGO authenticator but, for a variety of reasons, doing the authentication in IIS was a better fit for their environment. We wrote a very simple Identity Asserter that consumed the Proxy-Remote-User HTTP header, stripped off the Windows domain name and asserted the remainder as the username.

How do you protect the WebLogic Server in this architecture?

There are really two options:

  1. two-way SSL between the web server and WebLogic Server
  2. firewalling


Two-way SSL between the web server and WebLogic Server both protects the data sent by encrypting it but also prevents access to the WebLogic Server from any client that doesn't have an appropriate client certificate. The actual steps are covered in the documentation for the ISAPI plug-in for IIS and for the Apache module. Using SSL requires certificates and imparts a performance impact, the magnitude of the impact depends on the environment so we always recommend testing.

An alternative to using two-way SSL is to use a firewall to protect the WebLogic Server. You can use a network based firewall, the traffic filtering functionality built into your host Operating System, or WebLogic Network Connection Filters. No matter which of these you opt to use the objective is to insure that any HTTP traffic coming into the WLS server orignated at one of the Web Servers and not from somewhere else in your environment.


Update November 2010: Due to popular demand the source code to this Identity Asserter is available at https://sample-identity-asserters.samplecode.oracle.com/