2

我试图找到一种简单、灵活的方式将 JaaS 身份验证添加到 REST。我发现了一篇认为引导我走向正确方向的帖子(参见 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 过滤器来保护您的资源吗?我将使用任何可以将身份验证细节与泽西代码分开的方法。它不必是 servlet 过滤器。
  • “将其配置为使用 JaaS”是什么意思?最初的计划是使用 JaaS 保护当前的 API。下一阶段将是使整个 API 在线可用。围绕 API 调用使用 Jersey 包装器似乎是有意义的,但让 Grizzly 处理身份验证。我相信,那时灰熊必须与 JaaS 进行交互。
  • 您是否认为应该有一些配置可以简单地导致 grizzly 保护您的资源?我正在考虑对用户进行身份验证和基于角色授权用户访问资源的两步过程。这个想法是让 Grizzly 处理身份验证(使用 JaaS)和 Jersey 处理授权。
  • “我认为没有必要在 RESTful 资源中使用 cookie。” 删除 cookie 的使用会很棒,但是如何实现呢?系统需要知道用户是否经过身份验证。我宁愿不要求他们为每次通话传递用户名/密码/等。甚至每次调用都将会话令牌作为参数传递似乎“丑陋”。

另外,请注意我对 REST 还很陌生。我已经做 SOAP 几年了,所以我可能有一种“SOAP 偏见”,这可能使我对每个人都使用的一些明显、简单的解决方案视而不见。如果有更简单的方法,欢迎分享。我只是想尽可能多地学习。

4

2 回答 2

3

我不完全清楚“将其配置为使用 JaaS 进行身份验证”是什么意思。如果有一个简单的配置让 grizzly 强制执行 HTTP 身份验证保护 URL,我不知道。

我从其他问题和答案中假设您参考了您想要使用 servlet 过滤器。通常这是在 servlet 项目的 web.xml 文件中配置的。Grizzly 当然经常用于从代码启动服务器,而不是应用程序配置。当我以这种方式使用 grizzly 时,我注意到 GrizzlyWebContainerFactory 没有提供任何允许您指定 servlet 过滤器的 create() 版本。但是,我确实注意到同一个项目中的 ServletAdapter [1] 确实为您提供了这种能力。

至于过滤器本身,不幸的是,我不知道一个预先构建的 servlet 过滤器,它只是将 JaaS 配置的登录模块插入到您的应用程序中,因此您可能必须在那里编写一些代码。不过这并不多,只需选择基于 HTTP 的身份验证方法(例如 HTTP BASIC、DIGEST 等),相应地从请求中提取凭据,然后使用 JaaS 框架登录即可。我认为 RESTful 资源不需要 cookie。RESTful 架构风格不赞成保留会话。其他方面有很多关于 JaaS 的教程,所以我不会在这里详细说明。

一旦 JaaS 主题处于活动状态(消费者成功登录),您只需获取当前主题并使用 Subject.getSubject 方法检查活动主体和凭据。

无论如何,这个答案是专门提供更多关于使用 servlet 过滤器进行身份验证的详细信息,正如您在另一个(链接的)问题中所要求的那样。这不一定是在 jersey webapp 中进行身份验证的唯一方法,但它是一种相当简单的方法。我喜欢它,因为它使我无法在需要它的每个资源中注入重复的身份验证代码。

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

于 2009-11-09T01:07:47.547 回答
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();
  }
}
于 2009-11-05T23:15:25.503 回答