I’m trying to grant our nonprod quarkus container CORS permission to run to http://localhost:8080. I get the feeling I have just a stupid mistake in the configuration, but I’m just not seeing it. Maybe the curl commands I’m using to test the preflight are wrong?
quarkus-bom version 3.13.2
application.properties
<code>%nonprod.quarkus.http.cors=true
%nonprod.quarkus.http.cors.access-control-allow-credentials=true
%nonprod.quarkus.http.cors.methods=GET,POST,OPTIONS
%nonprod.quarkus.http.cors.origins=http://localhost:8080
%nonprod.quarkus.http.cors.headers=authorization,content-type,origin,accept,x-requested-with,access-control-allow-origin,access-control-request-method
<code>%nonprod.quarkus.http.cors=true
%nonprod.quarkus.http.cors.access-control-allow-credentials=true
%nonprod.quarkus.http.cors.methods=GET,POST,OPTIONS
%nonprod.quarkus.http.cors.origins=http://localhost:8080
%nonprod.quarkus.http.cors.headers=authorization,content-type,origin,accept,x-requested-with,access-control-allow-origin,access-control-request-method
</code>
%nonprod.quarkus.http.cors=true
%nonprod.quarkus.http.cors.access-control-allow-credentials=true
%nonprod.quarkus.http.cors.methods=GET,POST,OPTIONS
%nonprod.quarkus.http.cors.origins=http://localhost:8080
%nonprod.quarkus.http.cors.headers=authorization,content-type,origin,accept,x-requested-with,access-control-allow-origin,access-control-request-method
curl command
<code>curl "$API_SERVICE_HOST/api/portal/resources" -H "Origin: http://localhost:8080" -H "Access-Control-Request-Method: GET" -X OPTIONS -i
<code>curl "$API_SERVICE_HOST/api/portal/resources" -H "Origin: http://localhost:8080" -H "Access-Control-Request-Method: GET" -X OPTIONS -i
</code>
curl "$API_SERVICE_HOST/api/portal/resources" -H "Origin: http://localhost:8080" -H "Access-Control-Request-Method: GET" -X OPTIONS -i
I get a HTTP 403 response with access-control-allow-methods: GET,POST,OPTIONS and can see in the quarkus log
"@timestamp": "2024-09-09T14:40:45.482843394Z",
"logger_name": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"message": "Invalid origin http://localhost:8080",
"thread_name": "vert.x-eventloop-thread-1",
"application": "msg-dex-api"
<code>{
"@timestamp": "2024-09-09T14:40:45.482843394Z",
"logger_name": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"level": "DEBUG",
"message": "Invalid origin http://localhost:8080",
"thread_name": "vert.x-eventloop-thread-1",
"application": "msg-dex-api"
}
</code>
{
"@timestamp": "2024-09-09T14:40:45.482843394Z",
"logger_name": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"level": "DEBUG",
"message": "Invalid origin http://localhost:8080",
"thread_name": "vert.x-eventloop-thread-1",
"application": "msg-dex-api"
}
This is running keycloak authorization, but I have disabled the policy enforcer for OPTIONS method
<code>%nonprod.quarkus.keycloak.policy-enforcer.paths.4.path=/api/*
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.methods.1.method=OPTIONS
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.methods.1.scopes=ANY
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.methods.1.scopes-enforcement-mode=DISABLED
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.enforcement-mode=DISABLED
<code>%nonprod.quarkus.keycloak.policy-enforcer.paths.4.path=/api/*
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.methods.1.method=OPTIONS
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.methods.1.scopes=ANY
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.methods.1.scopes-enforcement-mode=DISABLED
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.enforcement-mode=DISABLED
</code>
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.path=/api/*
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.methods.1.method=OPTIONS
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.methods.1.scopes=ANY
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.methods.1.scopes-enforcement-mode=DISABLED
%nonprod.quarkus.keycloak.policy-enforcer.paths.4.enforcement-mode=DISABLED
And I don’t include the Origin header I do get a 200 response, so the authorization server should not be interfering with the Options request.
<code>curl "$API_SERVICE_HOST/api/portal/resources" -H "Access-Control-Request-Method: GET" -X OPTIONS -i
<code>curl "$API_SERVICE_HOST/api/portal/resources" -H "Access-Control-Request-Method: GET" -X OPTIONS -i
</code>
curl "$API_SERVICE_HOST/api/portal/resources" -H "Access-Control-Request-Method: GET" -X OPTIONS -i
Edit: curl -v headers (masked service address)
<code>> OPTIONS /api/portal/resources HTTP/2
> Host: $API_SERVICE_HOST
> origin: http://localhost:8080
> access-control-request-method: GET
<code>> OPTIONS /api/portal/resources HTTP/2
> Host: $API_SERVICE_HOST
> accept: */*
> origin: http://localhost:8080
> access-control-request-method: GET
</code>
> OPTIONS /api/portal/resources HTTP/2
> Host: $API_SERVICE_HOST
> accept: */*
> origin: http://localhost:8080
> access-control-request-method: GET
Any thoughts on what I might have wrong here?
Additional Edit. I went looking through the https://github.com/quarkusio/quarkus/blob/main/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/cors/CORSFilter.java
I’ve also tried different variants on what to put in origins based on what I found in the code in CORSFilter.java above
- %nonprod.quarkus.http.cors.origins=*
- %nonprod.quarkus.http.cors.origins=/.*/
With 1. the wildCardOrigin should have skipped past the !allowsOrigin checks entirely, but it still fails with a log state “Invalid origin http://localhost:8080” which I assume is line 153.
With 2. line 146 should have triggered true “|| isOriginAllowedByRegex(allowedOriginsRegex, origin)”, but I actually see a log entry from line 147 and isSameOrigin which shouldn’t happen. But here is the kicker, 147 is not logged if I send origin as * or http://localhost:8080, but is logged if I used https://www.google.com.
I also added https://www.google.com explicitly to the cors.origin and same result, the isSameOrigin line get logged, which with a match and lazy evaluation shouldn’t have happened if I had this correct.
For some reason this makes me think there is a different CORSFilter used on http vs https schemes.
EDIT 3 (Adding additional logging)
"@timestamp": "2024-09-10T14:10:23.790612802Z",
"loggerClassName": "org.jboss.logging.Logger",
"logger_name": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"message": "Same origin check has failed, the host values do not match. Request URI: https://msg-dex.myhost.com/api/portal/resources, origin: https://localhost:8080",
"thread_name": "vert.x-eventloop-thread-1",
"hostName": "99c748b91cb6",
"processName": "/usr/lib/jvm/java-17-amazon-corretto/bin/java",
"sourceClassName": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"sourceFileName": "CORSFilter.java",
"sourceMethodName": "isSameOriginSlowPath",
"sourceModuleName": null,
"sourceModuleVersion": null,
"application": "msg-dex-api"
"@timestamp": "2024-09-10T14:10:23.79163831Z",
"loggerClassName": "org.jboss.logging.Logger",
"logger_name": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"message": "Invalid origin https://localhost:8080",
"thread_name": "vert.x-eventloop-thread-1",
"hostName": "99c748b91cb6",
"processName": "/usr/lib/jvm/java-17-amazon-corretto/bin/java",
"sourceClassName": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"sourceFileName": "CORSFilter.java",
"sourceMethodName": "handle",
"sourceModuleName": null,
"sourceModuleVersion": null,
"application": "msg-dex-api"
"@timestamp": "2024-09-10T14:10:23.793910859Z",
"loggerClassName": "org.jboss.logging.Logger",
"logger_name": "io.quarkus.http.access-log",
"message": "OPTIONS HTTP_1_1XXX.XXX.136.209 X-Forwarded-For: XXX.XXX.136.209nX-Forwarded-Proto: httpsnX-Forwarded-Port: 443nX-Amzn-Trace-Id: Root=1-66e0534f-506363231c716dc1753f91banorigin: https://localhost:8080naccess-control-request-method: GETnhost: msg-dex.myhost.com",
"thread_name": "vert.x-eventloop-thread-1",
"hostName": "99c748b91cb6",
"processName": "/usr/lib/jvm/java-17-amazon-corretto/bin/java",
"sourceClassName": "io.quarkus.vertx.http.runtime.filters.accesslog.JBossLoggingAccessLogReceiver",
"sourceFileName": "JBossLoggingAccessLogReceiver.java",
"sourceMethodName": "logMessage",
"sourceModuleName": null,
"sourceModuleVersion": null,
"application": "msg-dex-api"
<code>{
"@timestamp": "2024-09-10T14:10:23.790612802Z",
"sequence": 198,
"loggerClassName": "org.jboss.logging.Logger",
"logger_name": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"level": "DEBUG",
"message": "Same origin check has failed, the host values do not match. Request URI: https://msg-dex.myhost.com/api/portal/resources, origin: https://localhost:8080",
"thread_name": "vert.x-eventloop-thread-1",
"threadId": 23,
"mdc": {},
"ndc": "",
"hostName": "99c748b91cb6",
"processName": "/usr/lib/jvm/java-17-amazon-corretto/bin/java",
"processId": 1,
"sourceClassName": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"sourceFileName": "CORSFilter.java",
"sourceMethodName": "isSameOriginSlowPath",
"sourceLineNumber": 259,
"sourceModuleName": null,
"sourceModuleVersion": null,
"application": "msg-dex-api"
}
{
"@timestamp": "2024-09-10T14:10:23.79163831Z",
"sequence": 199,
"loggerClassName": "org.jboss.logging.Logger",
"logger_name": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"level": "DEBUG",
"message": "Invalid origin https://localhost:8080",
"thread_name": "vert.x-eventloop-thread-1",
"threadId": 23,
"mdc": {},
"ndc": "",
"hostName": "99c748b91cb6",
"processName": "/usr/lib/jvm/java-17-amazon-corretto/bin/java",
"processId": 1,
"sourceClassName": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"sourceFileName": "CORSFilter.java",
"sourceMethodName": "handle",
"sourceLineNumber": 153,
"sourceModuleName": null,
"sourceModuleVersion": null,
"application": "msg-dex-api"
}
{
"@timestamp": "2024-09-10T14:10:23.793910859Z",
"sequence": 200,
"loggerClassName": "org.jboss.logging.Logger",
"logger_name": "io.quarkus.http.access-log",
"level": "INFO",
"message": "OPTIONS HTTP_1_1XXX.XXX.136.209 X-Forwarded-For: XXX.XXX.136.209nX-Forwarded-Proto: httpsnX-Forwarded-Port: 443nX-Amzn-Trace-Id: Root=1-66e0534f-506363231c716dc1753f91banorigin: https://localhost:8080naccess-control-request-method: GETnhost: msg-dex.myhost.com",
"thread_name": "vert.x-eventloop-thread-1",
"threadId": 23,
"mdc": {},
"ndc": "",
"hostName": "99c748b91cb6",
"processName": "/usr/lib/jvm/java-17-amazon-corretto/bin/java",
"processId": 1,
"sourceClassName": "io.quarkus.vertx.http.runtime.filters.accesslog.JBossLoggingAccessLogReceiver",
"sourceFileName": "JBossLoggingAccessLogReceiver.java",
"sourceMethodName": "logMessage",
"sourceLineNumber": 44,
"sourceModuleName": null,
"sourceModuleVersion": null,
"application": "msg-dex-api"
}
</code>
{
"@timestamp": "2024-09-10T14:10:23.790612802Z",
"sequence": 198,
"loggerClassName": "org.jboss.logging.Logger",
"logger_name": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"level": "DEBUG",
"message": "Same origin check has failed, the host values do not match. Request URI: https://msg-dex.myhost.com/api/portal/resources, origin: https://localhost:8080",
"thread_name": "vert.x-eventloop-thread-1",
"threadId": 23,
"mdc": {},
"ndc": "",
"hostName": "99c748b91cb6",
"processName": "/usr/lib/jvm/java-17-amazon-corretto/bin/java",
"processId": 1,
"sourceClassName": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"sourceFileName": "CORSFilter.java",
"sourceMethodName": "isSameOriginSlowPath",
"sourceLineNumber": 259,
"sourceModuleName": null,
"sourceModuleVersion": null,
"application": "msg-dex-api"
}
{
"@timestamp": "2024-09-10T14:10:23.79163831Z",
"sequence": 199,
"loggerClassName": "org.jboss.logging.Logger",
"logger_name": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"level": "DEBUG",
"message": "Invalid origin https://localhost:8080",
"thread_name": "vert.x-eventloop-thread-1",
"threadId": 23,
"mdc": {},
"ndc": "",
"hostName": "99c748b91cb6",
"processName": "/usr/lib/jvm/java-17-amazon-corretto/bin/java",
"processId": 1,
"sourceClassName": "io.quarkus.vertx.http.runtime.cors.CORSFilter",
"sourceFileName": "CORSFilter.java",
"sourceMethodName": "handle",
"sourceLineNumber": 153,
"sourceModuleName": null,
"sourceModuleVersion": null,
"application": "msg-dex-api"
}
{
"@timestamp": "2024-09-10T14:10:23.793910859Z",
"sequence": 200,
"loggerClassName": "org.jboss.logging.Logger",
"logger_name": "io.quarkus.http.access-log",
"level": "INFO",
"message": "OPTIONS HTTP_1_1XXX.XXX.136.209 X-Forwarded-For: XXX.XXX.136.209nX-Forwarded-Proto: httpsnX-Forwarded-Port: 443nX-Amzn-Trace-Id: Root=1-66e0534f-506363231c716dc1753f91banorigin: https://localhost:8080naccess-control-request-method: GETnhost: msg-dex.myhost.com",
"thread_name": "vert.x-eventloop-thread-1",
"threadId": 23,
"mdc": {},
"ndc": "",
"hostName": "99c748b91cb6",
"processName": "/usr/lib/jvm/java-17-amazon-corretto/bin/java",
"processId": 1,
"sourceClassName": "io.quarkus.vertx.http.runtime.filters.accesslog.JBossLoggingAccessLogReceiver",
"sourceFileName": "JBossLoggingAccessLogReceiver.java",
"sourceMethodName": "logMessage",
"sourceLineNumber": 44,
"sourceModuleName": null,
"sourceModuleVersion": null,
"application": "msg-dex-api"
}