The blog that aims at the largest possible balance of pleasure over pain

Main menu

Tag Archives: ldap

Post navigation

Overview

I’ve been merrily creating my ExtJS 4 application when the inevitable came that we must secure the application. Of course it doesn’t stop at authentication, especially in a client-side where nothing should be assumed secure; the users of course want to show/hide, enable/disable things using role-based security. In a previous life, I used Spring Security to do this sort of thing for Java applications, so I wondered why I couldn’t just do the same for ExtJS. This article shares a complete example to do exactly that. Here I will show you how you can use your existing IT infrastructure to secure your application (in my case LDAP and Siteminder) and how to integrate Spring Security 3.0 with ExtJS 4. Lastly, I would like to thank Dmitry and Rajesh for their contributions on this topic.

Authentication

The first step is to step up authentication to your application. The first approach I’ll show is using LDAP authentication (authn) followed by Siteminder authn. To set-up LDAP authn, you have to extend your HTML/JS/CSS3 app to a Java EE Spring application. There are already several articles on the Web on how to do this and most of today’s IDEs can go this for your automatically. Once you have created your Java EE app, you need to configure your web.xml. The basic gist of it is that you will be using a servlet filter to intercept URLs that invoke the application (see DelegatingFilterProxy). Here is an example one:

In your Spring applicationContext.xml you’ll want to create and import another spring context configuration that contains security specifics. In the example that follows, I show how you can do LDAP authentication:

Here I do an anonymous bind over the LDAPS port to authenticate based on the users’ credentials they provide (be sure you use SSL and take the time to set up your JVM to support it with our internal certs). The intercept-url includes a pattern (I did everything with “/**”) and the type of access (I did “isAuthenticated()” and defer authorization till later). You’ll see I have commented out access using hasRole(‘ROLE_LDAP_GROUP’) which can be used to limit the users able to open the application using an LDAP group, but I didn’t want to do that. In the next example, I show how you can do the same thing with Siteminder:

While this has been all going on, it is necessary to block the Ext JS app until we have confirmed the identity of the user. In Ext JS we can set up an Ajax request to do that and use the success listener to block the viewport from being created until success is achieved. You’ll notice that my Ajax request is a HTTP POST to user/getUser. This is the mechanism I used to determine the principal from the server-side by parsing the JSON returned into the roles array for the application, which I’ll go into in a little bit.

Now, let’s take a look at the UserController Java class. This is the class that is responsible for determining the user and retrieving his/her roles. What is really nice about Spring is that I can use their MVC controller mechanism and annotations to intercept URLs and do some sort of logic with a simple POJO as follows:

Notice I use the Spring’s SecurityContextHolder to retrieve the principal as well as his/her authorities (i.e., roles). I populate those into a User bean, convert that to JSON and return the result to the client. Once this information is provided to the client, we can manage roles effectively on the client side.

Authorization

Now that we’ve authenticated the user, collected their roles and parsed them into the Ext.application’s roles array, how can we use that in the application to protect components. The answer is simple really, you just add some conditional logic for the components config for either “hidden” or “disabled”. For instance, I had a settings Tab on a tab panel that only administrators should see. I was able to accomplish that with this bit of JavaScript code:

As you can see from above, I simply have hasRole return true or false based on whether the user has a given role established at the time we invoked the application and made the AJAX call to getUser() from the previous section. If the user is in the LDAP group “UI.ADMIN” (NOTE: Spring automatically prepends ROLE_), they are granted access to see the tab.

Now you might be saying, well I could write a greasemonkey script and hack the JavaScript so I could see the tab and indeed you can, but the approach I demonstrate is only used to change the behavior of the application, not the functionality. Let’s say you applied this to a “save” button instead, that save button is going to call some server-side functionality to, well, save. You should definitely check on the server-side that the user can execute save functions (in the example below, updateDriver). It would be folly to expect a client-side application to verify this. Again, Spring Security to the rescue with a simple annotation, @PreAuthorize, to the server-side method to check the role of the user as follows:

Even before this method gets invoked, if the user does not have that role, they will get a 403 exception and thus preventing them from accessing the save operation.

Data Security

Another aspect of security for your application to consider should be the data itself. For instance, you may show a grid of data but one user is authorized to see more information than another. This is controlled with identity propagation to the underlying services. This means that with Siteminder, the users secure, time-based identity will be propagated in the HTTP header downstream to the underlying services. The services can validate the users authorities by parsing the header for the principal and querying data appropriately based on that user’s identity. Thus, the data returned will be unique for that user. It’s important to make sure your underlying services do this sort of checking.

Another approach is to use a secure token service (STS) and SAML assertions. This is especially popular in SOA’s. More information can be found in Thomas Erl’s seminal work on the topic.

Conclusion

Security is essential to all business-based Web applications and so it needs to be carefully thought out. Here I hope I’ve provided useful information on how you can implement your customer’s security requirements for an Ext JS application using Spring Security. You have to assume nothing is ever secure on a client-side application, so you must include a server-side component to ensure your application is secure.

I recently was put on a project to explore how we could use GIT over HTTP and integrate with our existing LDAP for authnz. The reason for HTTP is that it is pretty easy to set-up and you can encrypt the content transfer with SSL. Also, HTTP/S is firewall friendly. The downside is that HTTP is a “dumb” protocol. The information here consolidates some information I found on the web to accomplish this. I am using RHEL 6, Apache 2.2, OpenLDAP and msysgit for my GIT client on my Windows machine.

First off, HTTP wasn’t necessarily the fastest protocol to use with GIT until they added a mod called git-http-backend, or SMART-HTTP, as of GIT 1.6.6. This article from the Pro GIT author, @chacon, details this and from my experience I cut my download times by two-thirds using this approach. Moreover, github is also supporting this. Basically what you need to do is as follows:

For LDAP authorization, of course you may have several different repos running off the same host, all which require certain users or groups access to the given location. This site explains this in detail, but here is an example I used so that I could bind a particular repo location to an LDAP group with SSL in place:

In this example, I’m binding project.git (use wildcard for LocationMatch in-case users forget to add .git extension) to any member in the LDAP group “my.group”. Note that you may need to define a different LDAP group attribute to match the field that will contain the DN of your users . If you are not storing DN, then you can set AuthLDAPGroupAttributeIsDN to off.

The last step is enable SSL on your Apache server. We use self-signed CERTs internally so you’re going to have to add those certs to your GIT clients unless of course your using a well known root CA like Verisign. To do that with msysgit, you open the $MYSYSGIT_INSTALL/bin/curl-ca-bundle.crt and add the base-64 encoded text of your keys to the end of this file. Then run the following command from the GIT BASH:

Post navigation

Hi, I'm a Solutions Architect for a major Telecom company. I design and develop software solutions leveraging several Java and JavaScript based platforms including ExtJS, Node.js, Spring, etc. I am also experienced using relational and NoSQL database solutions like MongoDB. I help evangelize Rich Internet Applications and open source technologies in Web application development, Web services, search, and developer collaboration. I graduated from the University of Michigan with a M.S. in Computer Science.
Note these views are my personal views and do not necessarily reflect the views of my employer. All code on this site is licensed under BSD.