User1
User1

Reputation: 41163

Using JaaS with Jersey on Grizzly

I'm trying to find a simple, flexible way to add JaaS authentication to REST. I found a post that I think leads me in the right direction (See StevenC's answer). It sounds like the servlet container is responsible for security, not the Jersey code itself. I like this idea, but need a little guidance on implementation.

Grizzly is my servlet container and I want to configure it to use JaaS for authentication. For now, a simple username/password combination would be fine, and hard-coding the username/password pairs directly in code is fine. As long as it uses JaaS, we can refine those details later.

As far as what is sent over HTTP, I'm thinking that storing a cookie would be the easiest way to make this all work. Whatever it takes to keep authentication junk away from my Jersey code.

Here's the code to start Grizzly so far:


final String baseUri = "http://localhost:9998/";
final Map initParams = new HashMap();

initParams.put("com.sun.jersey.config.property.packages", 
  "my.jersey.Service");

System.out.println("Starting grizzly...");
SelectorThread threadSelector = GrizzlyWebContainerFactory.create(baseUri, initParams);
System.out.println(String.format(
        "Jersey app started with WADL available at %sapplication.wadl\n"
  + "Try out %shelloworld\nHit enter to stop it...", baseUri, baseUri));                
System.in.read();
threadSelector.stopEndpoint();
System.exit(0);

If this whole process works, what's the best way to check permissions for the user? I would probably want my REST code to actually validate permissions at certain points. Am I even on the right track? Is there an easier way? A link to a tutorial would be a great answer. Even an answer like "I did that and it worked" would give me a warm fuzzy that I'm heading in the right direction.

Thanks for any help.

EDIT: Some clarifications for StevenC's comment:

Also, please note that I'm fairly new to REST. I've been doing SOAP for a couple of years, so I may have a "SOAP bias" that may be blinding me from some obvious, simple solution that everyone uses. If there's an easier way, please feel free to share. I'm just trying to learn as much as possible.

Upvotes: 2

Views: 4526

Answers (2)

StevenC
StevenC

Reputation: 1172

I'm not entirely clear what is meant by "configure it to use JaaS for authentication". If there's a simple configuration to have grizzly enforce HTTP authentication protecting URLs, I don't know about it.

I'm assuming from the other question and answer you reference that you want to use a servlet filter. Normally that's configured in the web.xml file of a servlet project. Grizzly is of course often used to start up a server from code as opposed to application config. When I used grizzly in this way I noticed that GrizzlyWebContainerFactory didn't offer any versions of create() that allowed you to specify servlet filters. However I did notice ServletAdapter [1] in the same project that does give you that ability.

As for the filter itself, I unfortunately don't know of a pre-built servlet filter that simply plugs JaaS configured login modules into your application, so you'll likely have to write a bit of code there. It's not much though, just choose the HTTP based authentication method (e.g. HTTP BASIC, DIGEST, etc.), extract credentials from the request accordingly, and login using the JaaS framework. I don't see that a cookie would specifically be needed for RESTful resources. The RESTful architectural style frowns upon keeping sessions. There are plenty of tutorials about JaaS otherwise, so I won't elaborate on that here.

Once a JaaS subject is active (consumer successfully logged in) you can simply get the current subject and check the active principals and credentials using the Subject.getSubject method.

Anyway, this answer is specifically to give a bit more of the details around doing auth with servlet filters, as you requested in the other (linked) question. This isn't necessarily the only way to do auth in a jersey webapp, but it's a fairly straightforward way to do it. I like it because it keeps me from injecting repetitive auth code in each resource that needs it.

[1] https://grizzly.dev.java.net/nonav/apidocs/com/sun/grizzly/http/servlet/ServletAdapter.html

Upvotes: 3

Matthew Sowders
Matthew Sowders

Reputation: 1670

Not sure if you are asking how to secure each resource, but I found a presentation on javapassion that sounds like what you are looking for. He says to use @Context SecurityContext as a parameter.

  @Path("basket")
  // Sub-resource locator could return a different resource if a user
  // is a preferred customer:
  public ShoppingBasketResource get(@Context SecurityContext sc) {
    if (sc.isUserInRole("PreferredCustomer") {
      return new PreferredCustomerShoppingBaskestResource();
    } else {
      return new ShoppingBasketResource();
  }
}

Upvotes: 1

Related Questions