Jax-RS Filter将对象传递给资源

时间:2017-07-28 20:31:23

标签: java jax-rs

我想将用于身份验证的用户对象在过滤器中传递给资源。有可能吗?

我使用的是野生蝇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);
  }
}

1 个答案:

答案 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也会存在。