【问题标题】:jax-rs rest webservice authentication and authorizationjax-rs rest webservice 身份验证和授权
【发布时间】:2012-02-10 19:03:02
【问题描述】:

我有一个网络应用程序,它需要允许使用不同网络客户端(浏览器、本机移动应用程序等)的用户进行注册。登录后,他们可以访问受限内容或他们自己的内容(例如他们创建的条目等)。

到目前为止我做了什么:我创建了一个 jax-rs rest web 服务(我在 glassfish 上托管我的应用程序),它公开了以下方法:

  • 注册 - 用户 POST 的他想要的用户名/密码/电子邮件/等;如果用户名/电子邮件是唯一的,则在数据库中为该用户创建一个条目(我使用 Hibernate 进行持久化)
  • login - 用户 POST 的用户名和密码。如果他们没问题,就会创建一个 UUID 并将其返回给用户(这将用作未来请求的令牌)。我有一个名为 logedusers 的表,其中包含 userID、token、validSince 作为列。

这让我感到困惑。

假设我有另一个方法 getUserEntries,它应该返回用户创建的所有条目。为了更清楚地说明这一点,将有一个 Entry 表,其中包含以下字段:entryId、userId、text。

这里最好的方法是什么?

我现在要做的是发出一个获取请求并像这样传递令牌:

localhost:8080/myApp/getUserEntries?token=erf34c34

之后,如果令牌有效,我从 logedusers 表中获取用户 ID,并根据该用户 ID,获取所有条目并将它们作为 json 返回。

类似这样的:

@GET
@Path("getUserEntries")
@Produces(MediaType.APPLICATION_JSON)
public Response getUserEntries(@QueryParam("token") String token) {      
    String userId=getUserIdFromToken(token);
    if (userId == null){
        return Response.status(Response.Status.UNAUTHORIZED).build();
    } else {
        //get some data associated with that userId, put it in the response object and send it back
        return Response.ok().entity(response).build();
    }
}

但是,如果我有更多提供数据的方法被有效用户调用,会发生什么情况?

我必须在每个方法的开头都做这个检查。

我想让这个授权过程透明

所以,这里有两个主要问题:

  1. 这样的设计好吗?整个过程使用用户/密码进行身份验证,服务器创建并存储令牌并将其发送给用户,用户在以后的请求中发送令牌。
  2. 如果我有许多端点需要确定主叫用户的身份,我该怎么办?我可以用一些注释标记它们吗,使用某种安全提供程序/身份验证器(我可以在其中添加自己的验证逻辑 - 例如检查令牌是否不超过 5 天等)。

谢谢

【问题讨论】:

    标签: web-services glassfish authorization jax-rs token


    【解决方案1】:

    这个设计好吗?整个过程使用用户/密码进行身份验证,服务器创建并存储令牌并将其发送给用户,用户在以后的请求中发送令牌。

    还可以。概念级别还不错(前提是您完全可以自行注册),但界面需要进行大量调整。虽然是的,POST 注册和登录是正确的,但对于 web 应用程序的其余部分,如果需要,您应该将身份信息从上下文中提取出来,并在可能的方法级别使用基于角色的访问控制。

    请注意,您的容器内置了一整套身份验证和授权支持机制。使用它们。

    如果我有很多端点需要确定主叫用户的身份,我该怎么办?我可以用一些注释标记它们,使用某种安全提供程序/身份验证器(我可以在其中添加自己的验证逻辑 - 例如检查令牌是否不超过 5 天等)。

    他们需要身份吗?还是他们只需要知道允许用户访问它们?如果是后者,最简单的方法是在方法上放置一个合适的@RolesAllowed 注解,此时(使用合适的配置;参见JEE5 security docs)。如果是前者,您需要获取当前操作的HttpServletRequest 对象并调用其getUserPrincipal() 方法来获取用户的身份(如果他们尚未登录,则为null)。 This SO question 描述了如何获取请求对象;有几种可能的方法,但我建议通过 @Resource 注释进行注入。

    我不会允许用户通常通过@QueryParam 提供自己的身份;这很容易被滥用。您可以允许他们以这种方式询问其他用户,但是您需要根据当前用户是否被允许了解其他用户的任何信息来决定是否要告诉他们任何事情.这是真实应用程序中出现的那种复杂的安全问题,并且是需要当前已验证用户身份的一个好点。

    【讨论】:

      猜你喜欢
      • 2012-07-05
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      • 2013-07-30
      • 2012-07-27
      • 2015-12-18
      • 1970-01-01
      • 2014-05-26
      相关资源
      最近更新 更多