{"id":5669,"date":"2024-03-08T22:07:41","date_gmt":"2024-03-08T21:07:41","guid":{"rendered":"https:\/\/gpmfactory.com\/?p=5669"},"modified":"2024-03-08T23:16:24","modified_gmt":"2024-03-08T22:16:24","slug":"oracle-ords-and-apache-http-server-as-reverse-proxy","status":"publish","type":"post","link":"https:\/\/gpmfactory.com\/index.php\/2024\/03\/08\/oracle-ords-and-apache-http-server-as-reverse-proxy\/","title":{"rendered":"Oracle ORDS and Apache HTTP Server as reverse proxy"},"content":{"rendered":"\n<p>Goal: notes about setup of Oracle ORDS running in standalone mode and Apache http server (httpd) used as a reverse proxy.<\/p>\n\n\n\n\n\n<h3 class=\"wp-block-heading\">Reminders:<\/h3>\n\n\n\n<p>SOP: Single Origin Policy (Rules to be respected in Browsers to protect users)<br>CORS: Cross Origin Resource Sharing (way to bypass SOP)<\/p>\n\n\n\n<p>Httpd is used for accepting incoming requests in https.<br>It forwards trafic onto ORDS runing in standalone mode and in http protocol.<br>(we could decide to run ORDS in https, but it was not the case in my scenario)<\/p>\n\n\n\n<p>Because the difference in protocol (https &#8211;&gt; http) this a  CORS situation which is trapped by ORDS, and therefore wich triggers an error.<\/p>\n\n\n\n<p>In order to workaround this problem, we have to tell to httpd to forward informations about the fact that it&rsquo;s a normal operation .<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;entry key=\"security.forceHTTPS\"&gt;true&lt;\/entry&gt;\n\nIn the virtual host section, add the following directives\nRequestHeader set \"X-Forwarded-Proto\" expr=%{REQUEST_SCHEME}\nRequestHeader set \"X-Forwarded-SSL\" expr=%{HTTPS}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Debugging<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">At httpd level<\/h4>\n\n\n\n<p>Activate forensic mod at httpd level. <br>It&rsquo;s a good way for display header content. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;IfModule log_forensic_module&gt;\n        #ForensicLog ${APACHE_LOG_DIR}\/forensic.log\n        ForensicLog logs\/forensic.log\n&lt;\/IfModule&gt;\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">At ORDS level<\/h4>\n\n\n\n<p>Create a file like this <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#Example 1: Log messages to a file\nhandlers=java.util.logging.FileHandler\n.level=SEVERE\n\njava.util.logging.FileHandler.level=ALL\noracle.dbtools.level=ALL\n\n# full pathname for logging output file\njava.util.logging.FileHandler.pattern = \/tmp\/ords20.log\n\njava.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter<\/code><\/pre>\n\n\n\n<p>and start ORDS in a specific mode:<br><br><code>java -Djava.util.logging.config.file=\/home\/almalinux\/ords20\/config\/ords.properties -jar ords.war standalone<\/code><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Use case<\/h3>\n\n\n\n<p>Using Tabbed Postman extension triggers SOP problem even if CORS has been established.<br>ORDS 20.4 does not appear to implement CORS. This means that a browser that strictly follows the SOP rules will react by reporting an error.<\/p>\n\n\n\n<p>ORDS 23.2 implements CORS. This means that it sends a normal operating message back to the browser, even if the domain at the origin of the request (Origin attribute of the header) is different from the Host name.<\/p>\n\n\n\n<p>However, a tool like Tabbed Postman (as opposed to the Postman Desktop application) is developed as an extension to Chrome. It therefore respects the Chrome security model which is very strict, like that of all browsers.<br>This is particularly true on a POST type request. As the call is initiated from the test tool (and not included in a page loaded from a particular site), Tabbed Postman sends in the Origin variable of the HTTP header, the following value: <br><code>chrome-extension:\/\/coohjcphdfgbiolnekdpbcijmhambjff<\/code><\/p>\n\n\n\n<p>This can be observed by activating a log with the Forensic module on httpd.<\/p>\n\n\n\n<p>Apache can be configured to implement CORS. It transmits the HTTP header as is to ORDS which then detects a difference between the Origin variable and the Host variable containing the machine.domain name. Therefore, this is considered an SOP violation situation and ORDS returns an error to the caller. As it is a browser extension, the request is rejected<\/p>\n\n\n\n<p>The Postman Desktop or Curl development tools do not trigger the SOP check by default. This is why we can safely test POST type APIs with it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Consequences and actions<\/h3>\n\n\n\n<p>For unit tests, you will need to use Postman desktop and not the Chrome extension from the same publisher.<br>To complete the point, here are two methods to work around the issue with Tabbed Postman:<\/p>\n\n\n\n<p>Add the application to the list of authorized origins, either via the APEX interface or by calling a plsql api:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>begin\nords.set_module_origins_allowed(\np_module_name =&gt; 'rest-v2',\np_origins_allowed =&gt; 'chrome-extension:\/\/coohjcphdfgbiolnekdpbcijmhambjff');\ncommit;\nend;<\/code><\/code><\/pre>\n\n\n\n<p>Trusted origins can be configured through the <code>security.externalSessionTrustedOrigins<\/code> configuration parameter that defines a comma separated list of origins that are trusted to make CORS request. If this parameter is empty or not configured, then no CORS requests are allowed for the PL\/SQL gateway and results in a 403 Unauthorized status.<\/p>\n\n\n\n<p>Either by inserting a directive at the ssl.conf level:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>setEnvIf Origin ^chrome-extension.*$ IS_POSTMAN=true\nRequestHeader set \"Origin\" \"https:\/\/xxx.xxx.xxx\u2026\" env=IS_POSTMAN<\/code><\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Goal: notes about setup of Oracle ORDS running in standalone mode and Apache http server (httpd) used as a reverse proxy. Reminders: SOP: Single&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"ppma_author":[150],"class_list":["post-5669","post","type-post","status-publish","format-standard","hentry","category-non-classe"],"authors":[{"term_id":150,"user_id":1,"is_guest":0,"slug":"admin8700","display_name":"Patrick","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/209d5ed69b74d288390621ab4c1d3773?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts\/5669","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/comments?post=5669"}],"version-history":[{"count":16,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts\/5669\/revisions"}],"predecessor-version":[{"id":5693,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/posts\/5669\/revisions\/5693"}],"wp:attachment":[{"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/media?parent=5669"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/categories?post=5669"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/tags?post=5669"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/gpmfactory.com\/index.php\/wp-json\/wp\/v2\/ppma_author?post=5669"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}