我想将用于身份验证的用户对象在过滤器中传递给资源。有可能吗?
我使用的是野生蝇10(resteasy 3)
@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
@Inject
private UserDao userDao;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
logger.warn("Filter");
String uid = requestContext.getHeaderString("Authorization");
User user;
if((user = validateUser(uid)) == null) {
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED).build());
}
}
private User validateUser(String uid) {
return userDao.getById(uid);
}
}
答案 0 :(得分:3)
我有两种方法可以做到这一点。第一种可能是更标准的方式,但也是更多的代码。最终,您将注入用户作为请求的一部分。但是,此解决方案需要的第一件事是Principal。一个非常简单的可能是:
import java.security.Principal;
...
public class UserPrinicipal implements Prinicipal {
// most of your existing User class but needs to override getName()
}
然后,在您的过滤器中:
...
User user;
if((user = validateUser(uid)) == null) {
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED).build());
}
requestContext.setSecurityContext(new SecurityContext() {
@Override
public Principal getUserPrincipal() {
return user;
}
@Override
public boolean isUserInRole(String role) {
// whatever works here for your environment
}
@Override
public boolean isSecure() {
return containerRequestContext.getUriInfo().getAbsolutePath().toString().startsWith("https");
}
@Override
public String getAuthenticationScheme() {
// again, whatever works
}
});
在您想要用户的班级中,您可以执行以下操作:
@Path("/myservice")
public class MyService {
@Context
private SecurityContext securityContext;
@Path("/something")
@GET
public Response getSomething() {
User user = (User)securityContext.getUserPrincipal();
}
}
我已经通过这种方式实现了它并且效果非常好。但是,一种可以说更简单的方法是将用户存储在会话中:
@Context
private HttpServletRequest request;
...
User user;
if((user = validateUser(uid)) == null) {
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED).build());
}
request.getSession().setAttribute("user", user);
然后,在您的服务中:
@Path("/myservice")
public class MyService {
@Context
private SecurityContext securityContext;
@Path("/something")
@GET
public Response getSomething(@Context HttpServletRequest request) {
User user = (User)request.getSession().getAttribute("user");
}
}
第二种方法的缺点是,您实际上不再是无状态服务,因为您在某处存储状态。但即使你不使用它,HttpSession也会存在。