我正在尝试在嵌入式Jetty中禁用HTTP TRACE方法。在Jetty doc中,默认情况下禁用HTTP跟踪,但对于嵌入式,它仍然是启用的。我试图将trace作为安全约束禁用,就像在jetty.xml中一样。
ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS | ServletContextHandler.SECURITY);
servletHandler.setClassLoader(Server.class.getClassLoader());
servletHandler.setContextPath("/");
servletHandler.addEventListener(new ContextLoaderListener());
servletHandler.addServlet(new ServletHolder(new CXFServlet()), "/*");
servletHandler.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName());
servletHandler.setInitParameter("contextConfigLocation", BeansConfig.class.getName());
servletHandler.setInitParameter("javax.ws.rs.Application", DispatcherConfig.class.getName());
/*
* <security-constraint>
* <web-resource-collection>
* <web-resource-name>Disable TRACE</web-resource-name>
* <url-pattern>/</url-pattern>
* <http-method>TRACE</http-method>
* </web-resource-collection>
* <auth-constraint/>
* </security-constraint>
*/
Constraint constraint = new Constraint();
constraint.setName("Disable TRACE");
ConstraintMapping mapping = new ConstraintMapping();
mapping.setConstraint(constraint);
mapping.setMethod("TRACE");
mapping.setPathSpec("/"); // this did not work same this mapping.setPathSpec("/*");
ConstraintSecurityHandler securityHandler = (ConstraintSecurityHandler) servletHandler.getSecurityHandler();
securityHandler.addConstraintMapping(mapping);
soapUI的输出示例:
HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 143
Server: Jetty(9.0.6.v20130930)
TRACE / HTTP/1.1
Connection: keep-alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Host: 192.168.33.115
Accept-Encoding: gzip,deflate
答案 0 :(得分:4)
扩展Server类并覆盖handle()方法最适合我。
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
public class MyServer extends Server {
@Override
public void handle(HttpChannel<?> connection) throws IOException, ServletException {
Request request=connection.getRequest();
Response response=connection.getResponse();
if ("TRACE".equals(request.getMethod())){
request.setHandled(true);
response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
} else {
super.handle(connection);
}
}
}
答案 1 :(得分:2)
Jan的回答是有效的(当然)。但是,它会导致jetty在启动时打印警告。
WARNING ... SecurityHandler ... has uncovered http methods for path ...
为了避免这种情况,首先在Jan的答案中添加约束(禁用TRACE),然后添加另一个约束(允许除TRACE之外的所有约束)。我为每个ServletContextHandler
调用以下代码:
private void disableTraceMethodForHandler(final ServletContextHandler servletContextHandler) {
SecurityHandler securityHandler = servletContextHandler.getSecurityHandler();
if (securityHandler == null) {
securityHandler = new ConstraintSecurityHandler();
servletContextHandler.setSecurityHandler(securityHandler);
}
if (securityHandler instanceof ConstraintSecurityHandler) {
ConstraintSecurityHandler constraintSecurityHandler = (ConstraintSecurityHandler) securityHandler;
ConstraintMapping disableTraceMapping = new ConstraintMapping();
Constraint disableTraceConstraint = new Constraint();
disableTraceConstraint.setName("Disable TRACE");
disableTraceConstraint.setAuthenticate(true);
disableTraceMapping.setConstraint(disableTraceConstraint);
disableTraceMapping.setPathSpec("/");
disableTraceMapping.setMethod("TRACE");
constraintSecurityHandler.addConstraintMapping(disableTraceMapping);
ConstraintMapping enableEverythingButTraceMapping = new ConstraintMapping();
Constraint enableEverythingButTraceConstraint = new Constraint();
enableEverythingButTraceConstraint.setName("Enable everything but TRACE");
enableEverythingButTraceMapping.setConstraint(enableEverythingButTraceConstraint);
enableEverythingButTraceMapping.setMethodOmissions(new String[] {"TRACE"});
enableEverythingButTraceMapping.setPathSpec("/");
constraintSecurityHandler.addConstraintMapping(enableEverythingButTraceMapping);
}
}
我在1月份在Google的appengine-java-vm-runtime和this issue中找到the fix之后找到了这个解决方案。上面的代码应该和XML一样配置那里。
答案 2 :(得分:2)
您可以创建过滤器:
...
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
if ("TRACE".equalsIgnoreCase(httpRequest.getMethod())) {
httpResponse.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
chain.doFilter(request, response);
}
....
答案 3 :(得分:1)
在Constraint
对象上,您需要致电setAuthenticate(true)
,并确保不致电setRoles(String[])
。这使其等同于<security-constraint>
,其中<auth-constraint>
为空,禁止访问。
它与DefaultServlet
而不是CXFServlet
一起使用的原因是因为DefaultServlet
明确拒绝访问TRACE方法。
答案 4 :(得分:-1)
您的代码按原样运行。
package jetty;
import java.io.File;
import java.nio.file.Path;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.security.Constraint;
public class BanTraceExample
{
private static final Logger LOG = Log.getLogger(BanTraceExample.class);
public static void main(String[] args)
{
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(9090);
server.addConnector(connector);
Path basePath = new File(System.getProperty("test.base",System.getProperty("user.dir"))).toPath().toAbsolutePath();
LOG.info("Base Directory: {}",basePath);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS | ServletContextHandler.SECURITY);
context.setContextPath("/");
server.setHandler(context);
Constraint constraint = new Constraint();
constraint.setName("Disable TRACE");
ConstraintMapping mapping = new ConstraintMapping();
mapping.setConstraint(constraint);
mapping.setMethod("TRACE");
mapping.setPathSpec("/");
ConstraintSecurityHandler securityHandler = (ConstraintSecurityHandler)context.getSecurityHandler();
securityHandler.addConstraintMapping(mapping);
ServletHolder holderDef = new ServletHolder("test",DefaultServlet.class);
holderDef.setInitParameter("resourceBase",basePath.toString());
holderDef.setInitParameter("dirAllowed","true");
context.addServlet(holderDef,"/");
try
{
server.start();
server.join();
}
catch (Throwable t)
{
t.printStackTrace(System.err);
}
}
}
测试。
正常的GET请求:
$ curl http://127.0.0.1:9090/.gitignore
.classpath
.project
.settings
target/
*.swp
*.log
*~
跟踪请求:
$ curl -v -X TRACE http://127.0.0.1:9090/.gitignore
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 9090 (#0)
> TRACE /.gitignore HTTP/1.1
> User-Agent: curl/7.40.0
> Host: 127.0.0.1:9090
> Accept: */*
>
< HTTP/1.1 405 Method Not Allowed
< Date: Mon, 30 Mar 2015 21:48:53 GMT
< Cache-Control: must-revalidate,no-cache,no-store
< Content-Type: text/html; charset=ISO-8859-1
< Content-Length: 297
< Server: Jetty(9.2.10.v20150310)
<
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 405 </title>
</head>
<body>
<h2>HTTP ERROR: 405</h2>
<p>Problem accessing /.gitignore. Reason:
<pre> Method Not Allowed</pre></p>
<hr /><i><small>Powered by Jetty://</small></i>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact