Friday, July 25, 2008
If you have a BlackBerry that also happens to support WI-FI, you might be surprised to find out that your favorite networked application doesn't favor WI-FI over APN when you're in range.
In fact, these applications will never favor WI-FI over your regular data network link. This is because the BlackBerry operating system does not abstract this for the application programmer. In other words, unless the application programmer knows about this and explicitly codes support for WI-FI in his application, the application will never use WI-FI.
So how do you get WI-FI support in there? You have to append the magical string ";interface=wifi" to any URL that you want to open. So, assuming standard Java ME/CLDC network programming here, you would do something like:
String uri = "http://www.spectrumdt.com;interface=wifi";
HttpConnection c = (HttpConnection) Connector.open(uri);
Otherwise, your application will inform you that "Could not open tunnel - Max time out" or go over your regular data link.
And that's about it. Oh, and by the way, if you don't have WI-FI or you're out of range, the OS won't do you any favors and fall back to your regular data link, so you have to make sure to try out the regular data link in case of errors too.
Finally, I would like to say that this feature is mostly impossible to find in the BlackBerry documentation. I found it in a beta version of an upcoming manual. The only reason I noticed this is that my development BlackBerry doesn't have a sim card, the browser worked, but my application didn't. Also of interest, almost all non first party applications I tested couldn't use WI-FI either. I'm guessing quite a few people don't know about this.
Sunday, July 13, 2008
I went out looking for a solution to this recently and found very little information. A lot of questions unanswered led me to believe I was not the only one who wanted to do this. I present here a small sample on how to accomplish this.
Before presenting the sample, let's go over a few things first on why you would want to do this and more importantly why you still need an Ajax style security token for all your GWT services even after this is implemented.
The reasons you would want to do this? One is automatic single sign-on (SSO) if supported by your container, e.g., Glassfish supports SSO out of the box for its web, EJB and web services tiers. If you use j_security_check, you're in; you're into all these services. Furthermore, if you use a J2EE authorization agent like OpenSSO inside Glassfish, you're into any services or sites provided by that federation. So even if you’re fronting your application with GWT, your back end might be composed of all these elements and more.
This also allows you to use any standard security annotations in your EJBs or, if you're orchestrating like me, in OpenESB. You can do this because you now have a Java security principal setup inside the container.
This also allows you to leverage the clustering features, if any, of your application server. Glassfish, again, contains great out of the box support for clustering. Session replication and expiration is managed for you and it just works. One call can proceed on one server while the other can proceed on another while the caller remains completely oblivious to where its work is actually being executed.
What you can’t do however is assume that you should no longer have an object representing your logged in user in your GWT client code. GWT RPC calls are still out in the open with this technique, you should pass in at the very least your session id value as a parameter to the GWT remote call so that the RCP service can do validations.
I use NetBeans 6.1 and release candidate 1 of GWT 1.5 for this example. The idea is to use the RequestBuilder class to touch a resource that has been marked off limits by the container. We do this because the j_security_check, in Java EE 5 at least, cannot be invoked directly in a portable manner. When the server sees the access to the protected resource by an unknown, it redirects you to the login page. When this occurs, the method “onResponseReceived” is called. We ignore the redirect and submit our own form. The form just needs to have at least 3 named elements present:
- The form name, j_security_check
- The user name field, j_username
- The password field, j_password
If you don’t touch a protected resource first and simply submit your form immediately, you will find that you still don’t have a security principal since no login actually occurred in the container.
You would apply the same rules for defining a protected area than you would for a normal non-GWT application. You can see on how to do this in Glassfish and Tomcat by following the tutorial here.
Here is some sample code that fulfills a login on Java application server. I originally had more here in terms of error handling but it seemed it got to be too large for presentation purposes.