jax-rs rest webservice身份验证和授权

Tim*_*o89 7 authorization web-services glassfish jax-rs token

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

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

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

这是让我感到困惑的地方.

假设我有另一个方法getUserEntries,它应返回用户所做的所有条目.为了更清楚,将有一个包含以下字段的Entry表:entryId,userId,text.

这里最好的方法是什么?

我现在做的是,我发出一个get请求并传入令牌,如下所示:

localhost:8080/myApp/getUserEntries?token=erf34c34

之后,如果令牌有效,我从logedusers表中获取userID并基于该userId获取所有条目并将它们作为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();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果有更多方法提供数据(如果有效用户调用),会发生什么?

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

我想让这个授权过程透明化

那么,这里有两个主要问题:

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

谢谢

Don*_*ows 2

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

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

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

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

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

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