Author Topic: Redirect unauthenticated user  (Read 3410 times)

Offline mabj

  • Newbie
  • *
  • Posts: 8
Redirect unauthenticated user
« on: April 16, 2019, 01:57:13 PM »
Hello!

I'm using Roundcube as frontend for my company's mail service, but we have run into a problem. We want to prevent mail users that are not logged in to log in from the standard log in form. First the backstory.

We have two different pages, https://mycompany.net which is the "homepage" of my company and https://mail.mycompany.net which runs the Roundcube instance. We also have and API at https://api.mycompany.net which runs our backend with our customer database. We want all customers to log in to the mail via our homepage, because the login will set some additional cookies needed for our services to work.

This is what we have so far:

Our homepage has a login form, where the user posts username and password which is then sent to the API. The API then logs in to Roundcube using POST to https://mail.mycompany.net?_task=login with the appropriate data. On confirmation the API then responds to the user with a redirectUrl and several cookies, both the default Roundcube cookies and some additional cookies that we have. The homepage the opens up a new tab in the browser with Roundcube.

This all works flawlessly so that is not the problem. Our problem is that if the user were to log in using Roundcube's built in login form, our own cookies would not be set and our homepage will not work correctly (for logged in users) and some custom functionalities we build into roundcube using a custom built plugin, would also break.

So, my idea is that when a user who is not logged in goes to https://mail.mycompany.net, he/she should be redirected to https://mycompany.net/?error=401. I have tried adding this to our plugin like this:

Code: [Select]
class my_company_plugin extends rcube_plugin
{
    function init()
    {
        $this->load_config();
        $this->rcmail = rcmail::get_instance();

        $this->add_hook('startup', array($this, 'check_startup'));
    }

    function check_startup() {
        // Redirect if not logged in
        if (!empty($this->rcmail->config->get('homepage_url')) &&
            !empty($this->rcmail->config->get('app_domain')) &&
            (empty($_COOKIE['our_custom_cookie_one']) ||
             empty($_COOKIE['our_custom_cookie_two']) ||
             empty($_COOKIE['roundcube_sessid']) ||
             empty($_COOKIE['roundcube_sessauth']))
        ) {
            header('Location: '.$this->rcmail->config->get('homepage_url').'?error=401');
        }
    }
}

The redirect works in these two cases:

But the redirect does not work in the following case:
  • When the user tries to log in from the homepage via the API, Roundcube throws a 401 Unauthorized back at the user

I hope that I have managed to explain the situation well enough. Does anyone have any idea how to solve this?
« Last Edit: April 16, 2019, 06:18:33 PM by mabj »

Offline SKaero

  • Administrator
  • Hero Member
  • *****
  • Posts: 5,876
    • SKaero - Custom Roundcube development
Re: Redirect unauthenticated user
« Reply #1 on: April 17, 2019, 12:30:10 AM »
I'm guessing the problem is that your checking for "roundcube_sessid" and "roundcube_sessauth" since they wouldn't be set before the user is logged in. I think you could just remove the check for those two cookies and it would do what your looking for.

Offline mabj

  • Newbie
  • *
  • Posts: 8
Re: Redirect unauthenticated user
« Reply #2 on: April 17, 2019, 07:48:50 AM »
I tried that but unfortunately it did not work. We realised that I need to provide a header in the HTTP request so we can distinguish if the request is coming from our API or not.

Nut now I have another problem: The API now sends this header {'X-Company-Backend': 'fromapi'} together with the POST request. Nut I cannot find any way to see that header in the plugin. I tried $_SERVER['HTTP_X_COMPANY_BACKEND'] but doing the following:

Code: [Select]
class my_company_plugin extends rcube_plugin
{
    function init()
    {
        $this->load_config();
        $this->rcmail = rcmail::get_instance();

        $this->add_hook('startup', array($this, 'check_startup'));
    }

    function check_startup() {
        $companyHeader = empty($_SERVER['HTTP_X_COMPANY_BACKEND']) ? '_ERROR_NOT_SET_' : $_SERVER['HTTP_X_COMPANY_BACKEND'];
        setCookie('roundcube_req_header', $companyHeader, time()+60*60*24*365, '/', $this->rcmail->config->get('app_domain'));
    }
}

inside init() sets the cookie to "_ERROR_NOT_SET_".

Any further ideas?

Offline SKaero

  • Administrator
  • Hero Member
  • *****
  • Posts: 5,876
    • SKaero - Custom Roundcube development
Re: Redirect unauthenticated user
« Reply #3 on: April 17, 2019, 10:24:03 AM »
How are you doing the post API?

Offline mabj

  • Newbie
  • *
  • Posts: 8
Re: Redirect unauthenticated user
« Reply #4 on: April 17, 2019, 10:30:27 AM »
Never mind stupid me. At least now I've learned not to use cookies for debugging. Better to use logs instead  8)

Anyway, I solved it and if someone ends up with the same problem, this was my solution:

Code: [Select]
class my_company_plugin extends rcube_plugin
{
    function init()
    {
        $this->load_config();
        $this->rcmail = rcmail::get_instance();

        // REDIRECT USER TO HOMEPAGE IF TRYING TO ACCESS MAIL WITHOUT BEING LOGGED IN
        if (empty($_COOKIE['our_custom_cookie_one']) ||
            empty($_COOKIE['our_custom_cookie_two']) ||
            empty($_COOKIE['roundcube_sessid']) ||
            empty($_COOKIE['roundcube_sessauth']))
        {
            if (empty($_SERVER['HTTP_X_COMPANY_BACKEND']) ||
                $_SERVER['HTTP_X_COMPANY_BACKEND'] !== 'fromapi')
            {
                header('Location: '.$this->rcmail->config->get('homepage_url').'?ec=401');
                exit;
            }
        }
    }
}

As you can se I put it in the init method since if I used the startup hook instead, it did not fire every time.