我有一个Web应用程序,需要允许用户使用不同的Web客户端(浏览器,本机移动应用程序等)进行注册。登录后,他们可以访问受限制的内容或他们自己的内容(如他们创建的条目等)。
到目前为止我做了什么:我创建了一个jax-rs rest webservice(我在glassfish上托管我的应用程序),它暴露了以下方法:
这是让我感到困惑的地方。
假设我有另一个方法getUserEntries,它应该返回用户所做的所有条目。为了更清楚,将有一个包含以下字段的Entry表:entryId,userId,text。
这里最好的方法是什么?
我现在做的是,我发出获取请求并传递令牌:
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();
}
}
但是,如果有更多的方法在有效用户调用时提供数据,会发生什么?
我必须在每个方法的开头进行检查。
我想让这个授权过程透明
所以,这里有两个主要问题:
由于
答案 0 :(得分:2)
这个设计好吗?整个用户/通过身份验证,服务器创建并存储并向用户发送令牌,用户在将来的请求上发送令牌。
有点好。概念级别不是太糟糕(假设您完全没有自我注册),但界面需要进行大量调整。虽然是,POST注册和登录是正确的,对于您的其余webapp,您应该在需要时从上下文中提取身份信息,并在方法级别使用基于角色的访问控制。
请注意,您的容器内置了一整套身份验证和授权支持机制。使用它们。
如果我有许多端点需要确定主叫用户的身份,该怎么办?我可以使用某些注释标记它们,使用某种安全提供程序/身份验证器(我可以添加自己的逻辑进行验证 - 例如,检查令牌是否超过5天等)。
他们需要身份吗?或者他们只是需要知道允许用户访问它们?如果是后者,最简单的方法是在方法上放置一个合适的@RolesAllowed
注释(此时具有合适的配置;请参阅JEE5 security docs)。如果是前者,则需要获取当前操作的HttpServletRequest
对象并调用其getUserPrincipal()
方法来获取用户的身份(如果他们尚未登录,则为null )。 This SO question描述了如何获取请求对象;有几种可行的方法,但我建议通过@Resource
注释注入。
我不会做的是允许用户通过@QueryParam
正常提供自己的身份;这只是非常容易被滥用。您可以允许他们以这种方式询问其他用户,但是您需要根据当前用户是否被允许了解其他用户的任何内容来决定是否要告诉他们任何事情。 。这是真正的应用程序中出现的那种复杂的安全问题,并且是需要当前经过验证的用户身份的好点。