在Grizzly上使用JaaS和Jersey

时间:2009-11-05 17:02:47

标签: java rest jersey jaas grizzly

我正在尝试找到一种简单,灵活的方法来向REST添加JaaS身份验证。我找到了一个post,我认为这导致我朝着正确的方向前进(参见StevenC的回答)。听起来servlet容器负责安全性,而不是Jersey代码本身。我喜欢这个想法,但需要一点实施指导。

Grizzly是我的servlet容器,我想将其配置为使用JaaS进行身份验证。现在,一个简单的用户名/密码组合就可以了,直接在代码中硬编码用户名/密码对就可以了。只要它使用JaaS,我们可以稍后改进这些细节。

就通过HTTP发送的内容而言,我认为存储cookie将是使这一切全部工作的最简单方法。无论如何使身份验证垃圾远离我的泽西岛代码。

到目前为止,这是启动Grizzly的代码:


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);

如果整个过程有效,那么检查用户权限的最佳方法是什么?我可能希望我的REST代码在某些点实际验证权限。我是否走在正确的轨道上?有没有更简单的方法?指向教程的链接将是一个很好的答案。即使像“我这样做而且有效”这样的回答也会给我一个温暖的模糊,我正朝着正确的方向前进。

感谢您的帮助。

编辑:对StevenC评论的一些澄清:

  • 您是否仍希望使用servlet过滤器来保护资源?我将使用任何可以从Jersey代码中分离出身份验证详细信息的内容。它不一定是servlet过滤器。
  • “配置使用JaaS”是什么意思?最初的计划是使用JaaS保护当前的API。下一阶段将是在线提供整个API。在API调用周围有一个Jersey包装器似乎是有意义的,但是保持身份验证由Grizzly处理。我相信Grizzly必须与JaaS互动。
  • 您是否认为应该有一些配置只会让灰熊来保护您的资源?我正在考虑对用户进行身份验证和基于角色的两步流程,授权用户访问资源。我们的想法是让Grizzly处理身份验证(使用JaaS)和Jersey处理授权。
  • “我认为不需要使用RESTful资源的cookie。”删除cookie的使用会很棒,但如何实现呢?系统需要知道用户是否经过身份验证。我宁愿不要求他们为每个电话传递用户名/密码/等。甚至在每次调用时都将会话令牌作为参数传递似乎“丑陋”。

另外,请注意我对REST很新。我已经做了几年SOAP,所以我可能会有一个“SOAP偏见”,这可能会使我从一个每个人都使用的明显,简单的解决方案中眩目。如果有更简单的方法,请随时分享。我只是想尽可能多地学习。

1 个答案:

答案 0 :(得分:1)

不确定您是否在询问如何保护每个资源,但我在javapassion上发现了一个与您正在寻找的相似的演示文稿。他说使用@Context SecurityContext作为参数。

  @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();
  }
}