Home > Atmosphere, Comet, Websocket > Quick Tip: Using Apache Shiro with your Atmosphere’s WebSocket/Comet app.

Quick Tip: Using Apache Shiro with your Atmosphere’s WebSocket/Comet app.

Apache Shiro is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. When used with The Atmosphere Framework and a Servlet based Container, the security context of the thread that will execute the async operation may not carry the same SecurityContext, causing some unexpected issues.

As an example, let’s say you want to retrieve the user principal after you have suspended your request. Normally all you need to do is:

Subject currentUser = SecurityUtils.getSubject();

This work perfectly well when the request gets executed using the calling thread of the HTTP request, e.g. when the Servlet Container execute your Servlet.service method. Now when using the Atmosphere Framework, you may need to lookup the Subject once the async operation occurs: when a Broadcast (server side events) gets executed or when the suspended connection resume. Under that condition, doing SecurityUtils.getSubject() will NOT return the same value as when the call gets executed using the calling thread and hence can cause unexpected issues. The async Thread used in that case may be provided by the Servlet Container itself or by the Atmosphere’s BroadcasterConfig ExecutorServices. In both case, the security context is NOT the same as the original HTTP request thread, hence you should not call SecurityUtils API. Instead, one solution is to use the request attribute map and store the information required in it. As simple as:

request.setAttribute("subject", SecurityUtils.getSubject());

Then when the request resume or when a broadcast event occurs (inside your AtmosphereHandler#onStateChange method, your BroadcastFilter etc,), you can easily retrieve that information by doing:

Subject subject = request.getAttribute("subject");

The Request object is *always* the original object constructed by the Servlet Container when handling the HTTP request, hence attributes (and session) will always be available. This is a safe way to store Apache Shiro information.

For any questions or to download Atmosphere Client and Server Framework, go to our main site, use our Google Group forum, follow the team or myself and tweet your questions there! You can also checkout the code on Github.


About these ads
Categories: Atmosphere, Comet, Websocket
  1. July 14, 2011 at 5:51 pm

    Hi Jeanfrancois,

    This is cool stuff! Thanks for sharing.

    Also note that framework developers (e.g. the developers behind the Atmosphere Framework) can use the subject.execute* and subject.associateWith* methods within Atmosphere to ensure the Subject is retained on the thread that executes the asynchronous processing. For example:

    //in main request thread:
    Subject subject = SecurityUtils.getSubject();

    Runnable runnable = subject.associateWith( new Runnable() {
    public void run() {
    callAsynchronously(); //logic in here
    }
    }

    //dispatch asynchronous work:
    atmosphereFrameworkThreadPool.execute(runnable);

    Or, you can use one of Shiro’s out-of-the-box SubjectAware* ExecutorService implementations to do the above work automatically. Then you can do this:

    //see – no shiro code!:
    Runnable work = new Runnable() {
    public void run() {
    //do stuff
    }
    }
    executorService.submit(work);

    Either of these two approaches ensures that anyone can call SecurityUtils.getSubject() (as expected) and it will still return the correct Subject instance, even if the thread is not the original request thread.

    HTH!

    Best regards, and thanks again for the blog post!

    Cheers,

    Les

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 52 other followers

%d bloggers like this: