I have read several of the other answers and have tried a couple of suggestions, but no matter what I have tried to this point I am unable to exclude OPTIONS
as an allowed http-method for TOMEE/TOMCAT running in a Docker container.
The web.xml file is located in the /usr/local/tomee/webapps/ROOT/WEB-INF directory:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<resource-ref id="dataSource-appDB">
<res-ref-name>jdbc/app</res-ref-name>
<mapped-name>java:comp/env/jdbc/app</mapped-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<error-page>
<exception-type>org.springframework.security.web.firewall.RequestRejectedException</exception-type>
<location>/errors/400</location>
</error-page>
<error-page>
<exception-type>java.lang.IllegalArgumentException</exception-type>
<location>/errors/400</location>
</error-page>
<security-constraint>
<web-resource-collection>
<web-resource-name>restricted methods</web-resource-name>
<url-pattern>/v1/*</url-pattern>
<http-method>OPTIONS</http-method>
</web-resource-collection>
</security-constraint>
</web-app>
When I cURL an endpoint for the allowed http methods, OPTIONS
is still there:
>curl -i --request-target "*" -X OPTIONS http://localhost/v1/healthcheck.html
HTTP/1.1 200
Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS
Content-Length: 0
Date: Fri, 06 Jan 2023 16:00:14 GMT
Server: no information
I have tried running with/without <auth-constraint />
and get the same result.
Here is the Dockerfile running the container:
FROM amazoncorretto:11-alpine-jdk
ENV PATH /usr/local/tomee/bin:$PATH
RUN mkdir -p /usr/local/tomee
ENV TZ America/New_York
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ /etc/timezone
WORKDIR /usr/local/tomee
# add the things we need to build the image
RUN apk update \
&& apk add sudo \
&& apk add tar \
&& apk add gpg \
&& apk add curl \
&& apk add gpg-agent \
&& apk add bash
# add the users and sudo for the security scanner
RUN adduser -S tomee
RUN addgroup tomee \
&& addgroup tomee tomee
RUN addgroup sudo \
&& addgroup tomee sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# download and import the GPG keys
RUN set -x \
&& curl -fsSL 'https://www.apache.org/dist/tomee/KEYS' -o GPG_KEYS | awk -F ' = ' '$1 ~ /^ +Key fingerprint$/ { gsub(" ", "", $2); print $2 }' | sort -u \
&& gpg --import GPG_KEYS
# verify keys
RUN set -xe \
&& for key in $GPG_KEYS; do \
gpg --batch --keyserver hkp://keyserver.ubuntu.com --recv-keys "$key" || \
gpg --batch --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys "$key" ; \
done
# TOMEE variables
# Apache changes the version from time to time and removes the old version.
# When they do that, you have to go to https://dist.apache.org/repos/dist/release/tomee/ to what see version is available
# then match that here
ENV TOMEE_VER 8.0.13
ENV TOMEE_BUILD webprofile
# set up Apache/TOMEE
RUN set -x \
&& curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz.asc -o tomee.tar.gz.asc \
&& curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz -o tomee.tar.gz \
&& gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz \
&& tar -zxf tomee.tar.gz \
&& mv apache-tomee-${TOMEE_BUILD}-${TOMEE_VER}/* /usr/local/tomee \
&& rm -Rf apache-tomee-${TOMEE_BUILD}-${TOMEE_VER} \
&& rm -Rf /usr/local/tomee/webapps/docs \
&& rm bin/*.bat \
&& rm tomee.tar.gz* \
&& chown -R tomee:tomee /usr/local/tomee
# put everything in the right place with the correct permissions
COPY $PWD/server.xml /usr/local/tomee/conf/
RUN chown -R tomee:tomee /usr/local/tomee/conf
COPY $PWD/app-war/target/app/META-INF/ /usr/local/tomee/webapps/ROOT/META-INF/
COPY $PWD/app-war/target/app/WEB-INF/ /usr/local/tomee/webapps/ROOT/WEB-INF/
COPY $PWD/app-war/target/app.war /usr/local/tomee/webapps/ROOT.war
RUN chown -R tomee:tomee /usr/local/tomee/webapps/
USER tomee
EXPOSE 8080
CMD ["catalina.sh", "run"]
I start the container with docker-compose:
version: "3.0"
services:
app-internal:
image: job/app-internal:0.0.1500
container_name: app-internal
ports:
- "80:8080"
environment:
- SPRING_PROFILES_ACTIVE=l1,app-internal
- JBOSS_ENV=l1
- PLATFORM_ENV=aws
- DEV_ENV=local
- JAVA_OPTS=-Xmn100m -Xmx1024m -Xms1024m
Am I missing something obvious?
The <security-constraint>
doesn't influence the "Allow" header in OPTIONS replay.
The Allow header is based on existence of onX handlers in the servlet. It is implemented in HttpServlet.doOptions.
from Java™ Servlet Specification Version 2.5:
The OPTIONS request determines which HTTP methods the server supports and returns an appropriate heade. For example, if a servlet overrides doGet, this method returns the following header:
Allow: GET, HEAD, TRACE, OPTIONS