泽西岛请求过滤后未调用资源

时间:2015-03-15 04:21:43

标签: spring jersey jax-rs jax-ws servlet-filters

我定义了两个SpringServlet,其中一个指向自定义过滤器

@WebServlet(urlPatterns = { "/" }, initParams = {
    @WebInitParam(name = "com.sun.jersey.config.property.packages", value = "com.x.y.resource"),
    @WebInitParam(name = "com.sun.jersey.api.json.POJOMappingFeature", value = "true") })
public class JerseyServlet extends SpringServlet
{
}

@WebServlet(name = "secure", urlPatterns = "/secure/*", initParams = {
    @WebInitParam(name = "com.sun.jersey.config.property.packages", value = "com.x.y.resource"),
    @WebInitParam(name = "com.sun.jersey.spi.container.ContainerRequestFilters", value = "com.x.y.resource.OAuthFilter"),
    @WebInitParam(name = "com.sun.jersey.api.json.POJOMappingFeature", value = "true") })
public class JerseySecureServlet extends SpringServlet
{
}

我们的想法是,任何包含“/ secure /”的网址都会定向到OAuthFilter,以便通过OAuth标头验证请求。所有其他网址都是正常处理的。

对于发送到不包含“/ secure /”的URL的任何请求,将正确调用相应的JAX-RS资源类。但是,对于包含“/ secure /”的URL,可以正确调用OAuthFilter,但之后不会调用JAX-RS带注释的Resource类。

以下是安全资源示例

@Component
@Scope("request")
@Path("/secure/example")
public class SecureResource
{
    @GET
    ...
}

这是OAuthFilter

@Provider
@Component
public class OAuthFilter implements ContainerRequestFilter
{
    public static final String AUTHORIZED_USER = "authorized_user";

    @Autowired
    AccessTokenService accessTokenService;

    @Autowired
    UserService userService;

    @Context
    HttpServletRequest httpRequest;

    @Override
    public ContainerRequest filter(ContainerRequest containerRequest)
    {
        OAuthServerRequest request = new OAuthServerRequest(containerRequest);
        OAuthParameters params = new OAuthParameters();
        params.readRequest(request);

        String accessToken = params.getToken();

        if (accessToken == null)
        {
            throw new WebApplicationException(Status.UNAUTHORIZED);
        }

        String userId = accessTokenService.getUserIdForToken(accessToken);

        if (userId == null)
        {
            throw new WebApplicationException(Status.UNAUTHORIZED);
        }

        User user = userService.get(userId);

        if (user == null)
        {
            throw new WebApplicationException(Status.NOT_FOUND);
        }

        httpRequest.setAttribute(AUTHORIZED_USER, user);

        return containerRequest;
    }
}

看起来一旦选择了带有“/ secure / *”映射的JerseySecureServlet并且调用了OAuthFilter,则baseURI是“http:/ ip:port / context / secure”,路径只是“/ example”,并且没有资源对应于此路径,因此不会调用任何内容。我应该做什么而只是将此过滤器应用于包含“/ secure /”?

的网址

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题,但我不能100%确定我的解决方案是否正确。我已将过滤后的serlvet上的注释更改为@WebFilter,给我

@WebServlet(urlPatterns = { "/*" }, initParams = {
    @WebInitParam(name = "com.sun.jersey.config.property.packages", value = "com.x.y.resource"),
    @WebInitParam(name = "com.sun.jersey.api.json.POJOMappingFeature", value = "true") })
public class JerseyServlet extends SpringServlet
{
}

@WebFilter(urlPatterns = "/secure/*", initParams = {
    @WebInitParam(name = "com.sun.jersey.config.property.packages", value = "com.x.y.resource"),
    @WebInitParam(name = "com.sun.jersey.spi.container.ContainerRequestFilters", value = "com.x.y.resource.OAuthFilter"),
    @WebInitParam(name = "com.sun.jersey.api.json.POJOMappingFeature", value = "true") })
public class JerseySecureFilter extends SpringServlet
{
}

这是有效的。一个更好的解决方案将被接受。