Booked Scheduler Community Support
July 17, 2018, 05:18:47 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Booked is proud to recommend Shift Capsule in the employee shift scheduling space www.ShiftCapsule.com
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: Active Directory Single Sign On  (Read 395 times)
José
Newbie
*

Karma: 0
Posts: 1


« on: April 16, 2018, 01:20:59 PM »

Hello for all

Previously, sorry for my english.  Grin

I do not want to leave pass the opportunity to give the congratulations for the developer or developers who made Booked. It is a really great software.

I found this software looking for a solution for book or reserve spaces in our enterprise. It was a real problem for the administrators of this task using Excel, Outlook, Email... etc, etc... We are under a Windows 2012 Active Directory and for us the authentication in AD for all webs and portals we have are so important, because we use a lot of them, like GLPI, OTRS, Typo3 and others custom applications developed by us. That is why we decided to modify (a little modification) Booked to implement the single sign on.

And now, these are the tasks we did for implement the Active Directory Single Sign On in Booked:

Previously, It is absolutly necessary configure the Apache Server to allow SSPI and NTLM (in WAMP) or Kerberos (in LAMP) authentication. We are familiarized with it, because, as i said before, we had a lot of software running in Apache with the AD authentication implemented and we use Kerberos authentication for our applications because although our authentication environment is in Windows AD, most of our web applications are developed in PHP/MYSQL and we use LAMP for deploy them. Kerberos Authentication leave a server environment variable named REMOTE_USER, with the username of the user authenticated in the navigator.

You got to configure the AD parameters modifying the plugins/Authentication/ActiveDirectory/ActiveDirectory.config.php file setting the proper values of the AD to authenticate. It is important to set 'use.sso' parameter to true, because we are going to use it.

In our enterprise, we thought necessary to have two Index pages in Booked, Web/index.php (for AD SSO Auth) and Web/index_UP.php (for User/Password Auth). index_UP is an exact copy of the original index.php provided in the Standard distribution of Booked. So, when the user open Booked, the system is going to try to validate and login in the AD through Index.php with Kerberos credentials. If there are no Kerberos credentials or even we want to log in with a database user,  IndexUP.php page allows to login with user/password.

1) Modify the config/config.php file (or in the option menu in the application to set logout.url parameter to index_UP.php. This is for allow to have this two systems of authentication, SSO and User/Password. You got to set 'ActiveDirectory' in the authentication plugin parameter too.

2)Modify PageLoad method in LoginPresenter class in Presenters/LoginPresenter.php file:

    public function PageLoad()
        {
                if ($this->authentication->IsLoggedIn())
                {
                        $this->_Redirect();
                }

                $this->SetSelectedLanguage();

/*              if ($this->authentication->AreCredentialsKnown())
                {
                        $this->Login();
                }
*/
               $server = ServiceLocator::GetServer();
                $loginCookie = $server->GetCookie(CookieKeys::PERSIST_LOGIN);
                ..........


3) Add this lines in index.php before "if ($page->LoggingIn())" to force to log in if the user has authenticated in kerberos:

     define('ROOT_DIR', '../');

     if (!file_exists(ROOT_DIR . 'config/config.php'))
     {
             die('Missing config/config.php. Please refer to the installation instructions.');
     }

     require_once(ROOT_DIR . 'Pages/LoginPage.php');
     require_once(ROOT_DIR . 'Presenters/LoginPresenter.php');
    
     $page = new LoginPage();

    if (isset($_SERVER['REMOTE_USER']))
     {
         $page->login();
     }

     if ($page->LoggingIn())
     {
         $page->Login();
     }

     if ($page->ChangingLanguage())
     {
         $page->ChangeLanguage();
     }

     $page->PageLoad();


4) Modify AreCredentialsKnown() method in ActiveDirectory class in file plugins/Authentication/ActiveDirectory/ActiveDirectory.php. Like this:

        public function AreCredentialsKnown()
        {
                return isset($_SERVER['REMOTE_USER']);
                // return false;
        }
This modification is in order to validate than if the user has not introduced the password, the user has been authenticated by an external system, like Kerberos, that is validated in Validate() method in WebAuthentication Class[/i] in Presenters/WebAuthentication.php:

        public function Validate($username, $password)
        {
                if (empty($password) && !$this->authentication->AreCredentialsKnown())
                {
                        return false;
                }
                return $this->authentication->Validate($username, $password);
        }

5) Modify AdLdapWrapper class in plugins/Authentication/ActiveDirectory/AdLdapWrapper.php file adding this method to scope the adLDAP class property with the same name:

    public function getUseSSO()
    {
          return $this->ldap->getUseSSO();
    }

6) Finally, modify the ActiveDirectory plugin class in plugins/Authentication/ActiveDirectory/ActiveDirectory.php file, in Validate and Login methods:

        public function Validate($username, $password)
        {
                $connected = $this->ldap->Connect();

               $user = $username;
               if (empty($user) && $this->ldap->getUseSSO() && $this->AreCredentialsKnown())
                        $username = $_SERVER['REMOTE_USER'];


                $username = $this->CleanUsername($username);
                $this->password = $password;

                if (!$connected)
                {
                        throw new Exception('Could not connect to ActiveDirectory LDAP server. Please check your ActiveDirectory LDAP......');
                }

               $isValid = ((empty($user) && (this->ldap->getUseSSO()) || $this->ldap->Authenticate($username, $password));
                // $isValid = $this->ldap->Authenticate($username, $password);


                Log::Debug('Result of ActiveDirectory LDAP Authenticate for user %s: %d', $username, $isValid);

                if ($isValid)
                {
                        $this->user = $this->ldap->GetLdapUser($username);
                        $userLoaded = $this->LdapUserExists();

                        if (!$userLoaded)
                        {
                                Log::Error('Could not load user details from ActiveDirectory LDAP. Check your basedn setting. User: %s', $username);
                        }
                        return $userLoaded;
                }
                else
                {
                        if ($this->options->RetryAgainstDatabase())
                        {
                                return $this->authToDecorate->Validate($username, $password);
                        }
                }

                return false;
        }

        public function Login($username, $loginContext)
        {
           if (empty($username) && $this->ldap->getUseSSO() && $this->AreCredentialsKnown())
                    $username = $_SERVER['REMOTE_USER'];


                $username = $this->CleanUsername($username);
                Log::Debug('ActiveDirectory - Login() in with username: %s', $username);
                if ($this->LdapUserExists())
                {
                        Log::Debug('Running ActiveDirectory user synchronization for username: %s, $
                        $this->Synchronize($username);
                }
                else
                {
                        Log::Debug('Skipping ActiveDirectory user synchronization, user not loaded'$
                }

                return $this->authToDecorate->Login($username, $loginContext);
        }


And that is all. We have Booked running with AD SSO Authentication.

I hope this solution helps you to do this task.

Thanks for all.
« Last Edit: April 16, 2018, 01:47:06 PM by José » Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.20 | SMF © 2006-2007, Simple Machines Valid XHTML 1.0! Valid CSS!