1

I am trying to configure my eXist-db app for real production environment. This means usage of domain names instead of localhost or IP address. When I access the server via pure IP, everything works. When I access it via domain name, I can log on per page only. I log in, as soon as I try to visit another link (or the current one! again) on the app’s page, I am logged out.

My controller:

xquery version "3.0";

import module namespace login="http://exist-db.org/xquery/login" at "resource:org/exist/xquery/modules/persistentlogin/login.xql";

declare variable $exist:path external;
declare variable $exist:resource external;
declare variable $exist:controller external;
declare variable $exist:prefix external;
declare variable $exist:root external;

declare variable $local:login_domain := 'domain-x';
let $set-user := login:set-user($local:login_domain, (), false())

(: Here we are grabbing all names of user's groups. :)
let $user := request:get-attribute('domain-x.user')
let $groups := if ($user) then string-join(sm:get-user-groups($user), ', ') else 'NoGroup'

return
    if ($exist:path eq '/'or $exist:resource eq 'index.html') then
        <dispatch xmlns='http://exist.sourceforge.net/NS/exist'>
            <forward url='{$exist:controller}/index.html'/>
            <view>
                <forward url="{$exist:controller}/modules/view.xql"/>
            </view>
            <error-handler>
                <forward url="{$exist:controller}/error-page.html" method="get"/>
                <forward url="{$exist:controller}/modules/view.xql"/>
            </error-handler>
        </dispatch>
    else if (
                ($exist:path eq '/create-ebooks-search.html') or
                ($exist:path eq '/create-ebooks-list.html') or
                ($exist:path eq '/metadata-tool.html') or
                ($exist:path eq '/testing.html') or
                ($exist:path eq '/create-ejournals-list.html')
            )
        then
        if (contains($groups, 'editors')) then
            <dispatch xmlns="http://exist.sourceforge.net/NS/exist">
                <!-- All sites are placed in the 'secure' directory,
                    links to them are as if they were in the root of the app,
                    hence the forwarding. -->
                <forward url='{$exist:controller}/secure/{$exist:resource}'/>
                <view>
                    <forward url="{$exist:controller}/modules/view.xql">
                        <set-attribute name="hasAccess" value="true"/><!-- Only for reference -->
                        <set-attribute name="$exist:prefix" value="{$exist:prefix}/secure"/>
                        <set-attribute name="$exist:controller" value="{$exist:controller}"/>
                        <!-- This is very important, without this or similar header, authentication
                             does not work properly—login and logout does not work as expected,
                             on some sites is is detected by the template, on some it is not.
                             It is possible to use other headers, works as well:
                             private, no-store, max-age=0, no-cache, must-revalidate are useful.
                             It is necessary to use it for the forward action of the view. -->
                        <set-header name="Cache-Control" value="no-cache"/>
                    </forward>
                </view>
                <error-handler>
                    <forward url="{$exist:controller}/error-page.html" method="get"/>
                    <forward url="{$exist:controller}/modules/view.xql"/>
                </error-handler>
            </dispatch>
...

UPDATE

It seems it could be associated with cookies. If I try to log in on the page accessed via the IP address, there is a cookie called org.exist.login stored and passed across pages on the site. If I try to log in on the page accessed via the domain name, the cookie is missing.

UPDATE II

I am proxying via Redbird, my config:

var proxy = require('redbird')({
  port:80,
  ssl: {
    port: 443
  }
});
proxy.register('my-app.domain.com', 'http://xx.xx.xxx.xxx:8081/exist/apps/my-app', {
    ssl: {
      key: '../SSL-certs/dev-key.pem',
      cert: '../SSL-certs/dev-cert.pem',
      }
});

(I was not able to use letsencrypt, described in this question.)

Community
  • 1
  • 1
Honza Hejzl
  • 874
  • 8
  • 23
  • 1
    I assume you are using stock eXist (with its embedded Jetty HTTP server), and that you don't have any other server playing the role of reverse proxy (e.g., Apache, Nginx)? Also, which version of eXist? – Joe Wicentowski Jan 12 '17 at 12:39
  • It is 3.0.RC1 version. As a reverse proxy I use [Redbird](https://github.com/OptimalBits/redbird) (because it is very light and easy to set up). – Honza Hejzl Jan 12 '17 at 12:45
  • 1
    Can you ensure Redbird is active and not being bypassed in both scenarios - pure IP vs. domain name? Any chance you could post your Redbird configuration file, if you've customized it at all? Could be relevant. – Joe Wicentowski Jan 12 '17 at 13:04
  • I think it is not bypassed because without it the page simple won’t load. On the other hand I have no rule for pure IP so I think in the case of pure IP it is served by Jetty(?). Question updated. – Honza Hejzl Jan 12 '17 at 15:42

1 Answers1

1

I think this is really a Redbird question and has to do with whether Redbird is passing the host name to eXist and allowing eXist's set-cookie header with this host name back to the client. For comparison, see how history.state.gov's nginx is configured - https://github.com/HistoryAtState/hsg-project/blob/master/deploy/1861/etc/nginx/vhosts/1861.hsg.conf#L22-L24:

proxy_pass_header       Set-Cookie;
proxy_set_header        Host $host;
proxy_set_header        X-Real-IP $remote_addr;

See this article describing how cookies operate differently when only using an IP vs. when using a domain: How do browser cookie domains work?.

Since I've not used Redbird I can't provide exact guidance, but if you are unable to find Redbird's counterpart to these nginx directives, I'd suggest posting your question as one about Redbird.

Community
  • 1
  • 1
Joe Wicentowski
  • 5,159
  • 16
  • 26
  • I am closer with Apache but still struggling with sessions and cookies (for IE now). I will update the question later with some solution. For now I will mark your answer as valid. Thanks a lot. – Honza Hejzl Jan 16 '17 at 12:46