1

I have an Apache Server and an OpenResty Server (like NGINX sort of) running on the same server with the same domain name but different ports (e.g. 8443 and 8000). I might also want to have them on different servers but for now the same server.

I tried using an encrypted cookie and that sort of works, but there are some drawbacks to that since it might persist if it is not programmatically expired, and there are some other issues with that, although it does mostly work when using the same FQDN, although I did run into some rare problems with it not being readable on the OpenResty server, which is why I'm looking for a way to use a shared SESSION or some sort of token in the headers or another mechanism.

With the Cookie I'm just using an href and GET to open the page on the OpenResty server and reading the Cookie. I could be the params to pass in the URL using a GET, but I would prefer to keep those invisible and somewhat secure. I could also probably POST to that page, but I would prefer to use some other mechanism if that is possible. It is an SSL connection.

I think you can configure Apache and OpenResty to use the same PHP library (not sure, but I think so), so that might help.

I am not too familiar with OAuth or other mechanisms for authentication. I want to have the access be transparent such that when I set a SESSION or Cookie to allow the user access to a particular resource on the OpenResty server that they automatically have access to the resource that is authorized. I actually have the auth mechanism to the resource sort of set up already because the resource actually resides on another app server that is set up as a reverse proxy behind OpenResty. When I need is way to transfer the auth credentials from the Apache server page to a page on the OpenResty server.

Thanks.

There isn't really that much code. I'm using PHP. On the Apache side there is actually an Controller class that sets the cookie. That is an AJAX call (could be a problem, but it seems to work). That just returns a link via AJAX, and that is opened up in an iFrame on the calling page. That part works, and actually the Cookie seems almost always. If it is encrypted and set to expire after a short amount of time that is a workaround for now:

Sets the Cookie, Apache Server

public function upload_study() {
    
        $uploaderurl = "https://sias.dev:8443";
        $myip = $_SERVER['REMOTE_ADDR']; // https://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php
        $data = array("session_id" => session_id(), "userid" => $_SESSION['user_id'], "user_name" => $_SESSION['user_name'], "mrn" => $_POST['mrn'], "IPaddress" => $myip, "anon_normal" => "normal");
        $curlResult = (new OrthancModel())->APICall ("upload_notice", $data);
        //$data = Encryption::encrypt(json_encode($data));
        $data = json_encode($data);
        //setcookie("PACStoken",  $data, time() + Config::get('SESSION_RUNTIME'), Config::get('COOKIE_PATH'), Config::get('COOKIE_DOMAIN'), Config::get('COOKIE_SECURE'), Config::get('COOKIE_HTTP'));
         setcookie("PACStoken", $data, [
        'expires' => time() + Config::get('SESSION_RUNTIME'),
        'path' => Config::get('COOKIE_PATH'),
        'domain' => Config::get('COOKIE_DOMAIN'),
        'secure' => Config::get('COOKIE_SECURE'),
        'httponly' => Config::get('COOKIE_HTTP'),
        'samesite' => Config::get('COOKIE_SAMESITE'),
        ]);
        DatabaseFactory::logVariable($curlResult);
        $link = $uploaderurl;
        echo '{"success":"done", "link":"' . $link . '"}';
}

JS on Apache Server:

$(".uploadstudy").on("click", function(e) {

    e.preventDefault();
    $.ajax({
        type: "POST",
        url: '/OrthancDev/upload_study',
        dataType: "json",
        data: {mrn: $("#data-mrn").val(), "csrf_token": $("#CsrftokenAJAX").data("csrf")},
        context: $(this),
        beforeSend: function(e) {
            $("#spinner").css("display", "block");
        },
    })
    .done(function(data, textStatus, jqXHR) {
        if(data.success) {
        $("#dynamiciframe").append($('<iframe style="width:100%;border:none;margin:0px;overflow:scroll;background-color:transparent;height: 100vh;" class="vieweroverlay-content" id="viewerframe" src="' + data.link + '"></iframe>'));
        document.getElementById("myNav").style.width = "100%";
        $("body").css("overflow", "hidden");
        }
        else alert("error");
    })
    .fail(function( jqXHR, textStatus, errorThrown) {
    })
    .always(function(jqXHR, textStatus) {
        $("#spinner").css("display", "none");
    });
});

There is more on the OpenResty Server, but this is a piece of the cookie part:

if (isset($_COOKIE['PACStoken'])) {

//print_r($_COOKIE['PACStoken']);
//$cookie = json_decode(Encryption::decrypt($_COOKIE['PACStoken']));
$cookie = json_decode($_COOKIE['PACStoken']);
$_SESSION['userid'] = $cookie->userid;
$_SESSION['user_name'] = $cookie->user_name;
$_SESSION['anon_normal'] = $cookie->anon_normal;
$_SESSION['mrn'] = $cookie->mrn;
$ip = $cookie->IPaddress;
$auth = true;
if ($ip != $currentip) { 
$auth = false;
}

}
else {
  $auth = false;
}

I should say that it is possible to extract the data from the cookie and put that into a SESSION once the user hits the OpenResty page. I need that data to authenticate access to the resources on the reverse proxy. I can immediately unset and expire the cookies. I can try that. Just wondering how secure that is if:

  1. The Cookie is encrypted with the keys on the Apache and OpenResty servers.
  2. The Cookie is unset and expired immediately. Realistically, it would exist for probably seconds at the most.

There is a library that does the encryption and decryption, e.g.

//$data = Encryption::encrypt(json_encode($data));
SScotti
  • 2,158
  • 4
  • 23
  • 41

0 Answers0