我想将过滤器中用于身份验证的用户对象传递给资源。可能吗?
我使用的是 Wildfly 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);
}
}
最佳答案
我认为有两种方法可以做到这一点。第一种可能是更标准的方法,但代码也更多。最终您将注入(inject)用户作为请求的一部分。但是,此解决方案首先需要的是 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
}
});
在您想要 User 的类中,您可以执行以下操作:
@Path("/myservice")
public class MyService {
@Context
private SecurityContext securityContext;
@Path("/something")
@GET
public Response getSomething() {
User user = (User)securityContext.getUserPrincipal();
}
}
我已经按照这种方式实现了它并且效果很好。然而,一种可以说更简单的方法是将用户存储在 session 中:
@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,它仍然存在。
关于java - Jax-RS 过滤器将对象传递给资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45381946/