JAX-RS REST Web服务的身份验证和授权

8
我有一个Web应用程序,需要允许使用不同网络客户端(浏览器、本地移动应用程序等)的用户进行注册。登录后,他们可以访问受限内容或其自己的内容(如他们创建的条目等)。
我所做的:我创建了一个jax-rs rest webservice(我在glassfish上托管我的应用程序),公开了以下方法:
- 注册(register) - 用户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();
    }
}

然而,如果我有更多的方法可以在有效用户调用时提供数据,那会怎样呢?

我必须在每个方法的开头进行此检查。

我希望使这个授权过程透明化。

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

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

谢谢

1个回答

2

这个设计还可以吗?整个过程是用户/密码认证,服务器创建、存储并发送令牌给用户,用户在以后的请求中发送令牌。

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

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

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

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

我不会允许用户通常通过@QueryParam提供自己的身份信息;那只是极易被滥用的。您可以允许他们通过这种方式询问关于其他用户的信息,但然后您需要决定是否基于当前用户是否被允许知道其他用户的任何信息而告诉他们任何信息。这是一个在真实应用程序中出现的复杂安全问题,也是需要当前已验证的用户身份的好处。


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