Jersery 请求过滤器后未调用资源
Resource not invoked after Jersery Request Filter
我定义了两个 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/”的 URLs 都被定向到 OAuthFilter 以验证 OAuth headers 的请求。所有其他 URL 都正常处理。
对于发送到不包含“/secure/”的 URL 的任何请求,正确调用适当的 JAX-RS 资源 class。然而,对于包含“/secure/”的 URLs,OAuthFilter 被正确调用,但是 JAX-RS 注释资源 class 之后永远不会被调用。
这是一个安全资源示例
@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/”的 URL?
我已经解决了这个问题,但我不能 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
{
}
这行得通。比这个更好的解决方案将被接受。
我定义了两个 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/”的 URLs 都被定向到 OAuthFilter 以验证 OAuth headers 的请求。所有其他 URL 都正常处理。
对于发送到不包含“/secure/”的 URL 的任何请求,正确调用适当的 JAX-RS 资源 class。然而,对于包含“/secure/”的 URLs,OAuthFilter 被正确调用,但是 JAX-RS 注释资源 class 之后永远不会被调用。
这是一个安全资源示例
@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/”的 URL?
我已经解决了这个问题,但我不能 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
{
}
这行得通。比这个更好的解决方案将被接受。