我已经成功地使用 Jersey 创建了一个 REST Web 服务,并通过 java 安全注释对其进行了保护。
它看起来像这样
GET /users/ // gives me all users
GET /users/{id} // gives the user identified by {id}
POST /users/ // creates user
PUT /users/{id} // updates user identified by {id}
DELETE /users/{id} // delete user
我还设置了一个具有两个角色的 Realm :用户和管理员
我保护了所有方法,以便只有管理员可以访问它们。
现在我想免费提供
PUT /users/{id}
和 GET /users/{id}
方法,以便用户可以访问他们的拥有和 只有自己的资源。例子:
// user anna is logged in and uses the following methods
GET /users/anna // returns 200 OK
GET /users/pete // returns 401 UNAUTHORIZED
由于我找不到通过注释来配置它的方法,我正在考虑将 HTTP 请求传递给相应的方法以检查是否允许用户访问资源。
GET /users/{id}
看起来像这样方法:@GET
@Path("/users/{id}")
@RolesAllowed({"admin","user"})
@Produces(MediaType.APPLICATION_JSON)
public Response getUser(
@PathParam("id") String id,
@Context HttpServletRequest req
) {
HttpSession session = request.getSession(false);
if (session != null && session.getValue("userID").equals(id))
return getObject(User.class, id);
return Response.status(Status.UNAUTHORIZED).build();
}
我不喜欢这种方法,因为我认为我必须添加
userID
手动到 session 。编辑
谢谢 Will 和 Pavel :) 这是我的最终解决方案:
@Context
private SecurityContext security;
// ...
@GET
@Path("/users/{id}")
@RolesAllowed({"admin","user"})
@Produces(MediaType.APPLICATION_JSON)
public Response getUser(@PathParam("id") String id){
if (security.isUserInRole("user"))
if (security.getUserPrincipal().getName().equals(id))
return getObject(User.class, id);
else
return Response.status(Status.UNAUTHORIZED).build();
else
return getObject(User.class, id);
}
最佳答案
在 HttpServletRequest
,您可以调用getRemoteUser()
或 getUserPrincipal()
获取登录用户的身份。然后,您将继续像您正在做的那样专门允许或拒绝他们访问特定资源。
Blessed Geek 更具体地指的是 REST 方面关于无状态事务和 HTTP 身份验证的使用。虽然这在 REST 架构的更大范围内很重要,但它与您的特定问题的相关性较低,因为您没有指定针对 Java EE 应用程序使用的身份验证机制的类型,特别是因为身份验证是一个容器问题在 Java EE 中,不是应用程序问题。
如果您使用的是基本身份验证,那么您将使用 HTTP header 来管理身份验证和授权。如果您使用基于表单的身份验证,那么容器将通过 servlet session 为您管理它,从而使服务有状态(因为 session 是有状态的工件)。
但这与您的具体问题无关。
关于security - 如何保护 REST 资源,以便只有角色的单个用户可以访问它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9406258/