保护一个Jersey RESTful Web服务

4
我正在开发一个restful web服务,稍后将由Android应用程序使用。
现在,我正在寻找一种方法来保护我的资源访问:
我在网上找到了几种实现的方式,但我无法确定哪种是最合适的。 例如,我发现Oauth规范更适用于第三方应用程序,而这不是我的情况。
那么,什么是最适合保护jersey API的方法?如果有人能够提供任何教程/文档,我将不胜感激。
我正在使用Glassfish v4服务器和Jersey JAX-RS实现。

通常你的应用程序需要一种身份验证方式,可能是直接验证用户或使用OAuth。你的身份验证也可以是API密钥。你只需要找到一种适合你的用例的方式来传输密钥到应用程序中。 - njzk2
这是一个不错的问题,我曾经问过同样的问题,但一直没有得到合适的答案... - Leonardo
你是在寻找基于用户的身份验证还是所有 Android 客户端共享的共享令牌?身份验证是否适用于所有终端点(资源/ URL)?请参考此链接:https://dev59.com/E3RA5IYBdhLWcg3w6SRH#6393502。 - David W
2个回答

1

在查看了不同的选项后,我使用了身份验证过滤器和基本身份验证。非常容易实现。

一些示例代码:

您需要一个过滤器

public class AuthFilter implements ResourceFilter, ContainerRequestFilter {
  ...
}

还有一个安全上下文:

public class MySecurityContext implements SecurityContext {
  ...
}

还有一个用户类:

public class User implements Serializable, Principal {
  ...
}

最后,您可以像这样添加所需的过滤器:(将您的ResourceConfig对象传递给此函数)
private void prepareFilters(ResourceConfig rc) {
  rc.getProperties().put("com.sun.jersey.spi.container.ContainerRequestFilters",
          getClassListing(new Class[]{
            AuthFilter.class
          }));

  rc.getProperties().put("com.sun.jersey.spi.container.ContainerResponseFilters",
          getClassListing(new Class[]{
            CORSFilter.class, //You might not need this
            GZIPContentEncodingFilter.class //You might not need this
          }));

  rc.getProperties().put("com.sun.jersey.spi.container.ResourceFilters",
          getClassListing(new Class[]{
            RolesAllowedResourceFilterFactory.class
          }));
}

另外,您可以将 @Context SecurityContext securityContext; 添加到您的资源类或个别方法中以实现更细粒度的访问控制。SecurityContext 将被注入到您的资源上下文中,因此您可以每个请求访问用户对象。

使用这种设置,您可以在 REST 方法中注释 @PermitAll, @RolesAllowed 等,从而对 RESTful 接口进行良好的控制。

我刚刚用 Jersey 完成了我的无状态(无会话)用户身份验证和管理。如果您想要完整的示例或自己试试,请告诉我;)


0
最简单的方法是使用Java EE内置的容器管理安全模型来保护您的REST资源,如tutorial所述。它允许您基于存储在数据库或文件域在web.xml或类本身中的用户和角色来配置安全性。
缺点是您必须启动会话,提取JSESSIONID并在每个请求中发送它,以便服务器可以验证它,但这会使您的服务更具有“有状态性”,并违反REST架构的无状态性。
另一种方法是使用WebFilters实现自定义安全性,例如在每个请求中发送用户名和密码,并根据特殊数据库中的信息进行验证。如果信息与数据库中存储的信息不匹配,则可以在响应对象中返回重定向或特殊错误代码。

我认为最好的方法是使用OAuth2,如规范所述。根据您使用的客户端类型(桌面、网页、移动客户端),有不同的工作流程以及许多好处,比如为应用程序的特定范围(只读或完全访问等)创建令牌。谷歌提供了许多不同的API,可以通过同一个帐户访问。如果一个应用程序只需要来自日历API的数据,则请求的令牌只会给您访问此特定API的权限,而不是整个账户的资源(如邮件数据、笔记等)。另一个要点是安全处理与客户端解耦,客户端应用程序中不必存储密码。

您可以自己实现所有内容,也可以使用像这个这样的开源项目。它提供了关于其工作原理的描述,并且代码非常出色,但它对Spring框架有很多依赖。针对我的用例,我开始用纯Java EE 7代码替换它们,并基于这个开源项目的思想创建了一个解决方案。替换的原因是它更具未来性,并且在部署过程中避免了类加载器问题。

在Android应用程序中,可以实现身份验证器以安全地存储令牌。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接