apachemod-rewritemod-auth-openidc

Apache: how to rewrite a URL-encoded path that includes slashes?


I have a logout link that looks like:

https://example.com/oauth2callback?logout=https%3A%2F%2Fexample.com%2Floggedout.html

In other words, /oauth2callback?logout=https://example.com/loggedout.html, but it has to be URL-encoded. This is a bit of a handful, so I want the user to see https://example.com/keycloak/logout instead.

To do this I've added a rewrite rule:

AllowEncodedSlashes On
RewriteRule ^/keycloak/logout$ /oauth2callback?logout=https%3A%2F%2Fexample.com%2Floggedout.html [L,QSA]

This doesn't work. The Apache log shows, with rewrite debugging:

    init rewrite engine with requested uri /keycloak/logout, referer: https://example.com/
    ...
    applying pattern '^/keycloak/logout$' to uri '/keycloak/logout', referer: https://example.com/
    rewrite '/keycloak/logout' -> '/oauth2callback?logout=httpsAFFexample.comFloggedout.html', referer: https://example.com/
    split uri=/oauth2callback?logout=httpsAFFexample.comFloggedout.html -> uri=/oauth2callback, args=logout=httpsAFFexample.comFloggedout.html, referer: https://example.com/
    local path result: /oauth2callback, referer: https://example.com/
    prefixed with document_root to /var/www1/oauth2callback, referer: https://example.com/
    go-ahead with /var/www1/oauth2callback [OK], referer: https://example.com/

This ends up as a 404 - I can't tell if Apache is doing this because of the forward slashes, or because Keycloak doesn't understand the query string. Note that /oauth2callback is not a real location on the server - it's handled internally by mod_auth_openidc. I thought this might be a problem, so I've also tried the PT flag, but it didn't help.

I've tried lots of variations of this, with AllowEncodedSlashes either On or NoDecode, and other flags, including R and B. The logs for all of these show that Apache is producing a query string that looks like logout=httpsAFFexample.comFloggedout.html, so the encoding seems to be lost. Any ideas?


Solution

  • AllowEncodedSlashes On
    RewriteRule ^/keycloak/logout$ /oauth2callback?logout=https%3A%2F%2Fexample.com%2Floggedout.html [L,QSA]
    

    You don't need the AllowEncodedSlashes directive since the encoded slashes are not in the URL-path (they are in the query string).

    However, you do need to backslash-escape the literal % in the RewriteRule substitution string to prevent %3 and %2 being treated as backreferences (which don't exist - so are seen as empty strings - hence the missing characters in the rewritten URL, as seen in the Apache (debug) log).

    For example:

    RewriteRule ^/keycloak/logout$ /oauth2callback?logout=https\%3A\%2F\%2Fexample.com\%2Floggedout.html [QSA,L]