This object is in archive! 

Automatic SSO with company domain integration

Archived Robin 10 years ago

Hi,

I decided I would make a post instead of asking question everywhere and share my work on what I want to do.


So, we bought the corporate version for my company. The application work great but we have several custom things we would like to add.


The most important things we would like is an automatic SSO (Single Sign On) when an user connect from the company intranet network. What I mean is I don't want login/password typing anymore, I want the application recognize him directly.


All users of our company are registred in an Active Directory. I set up the LDAP sso with the interface and it works.


But now I want it to be automatic. I configured our web server with a Kerberos authentication and now in my applicatio when I call the variable $_SERVER['AUTH_USER'] I have the username of the guest. (DOMAIN\USERNAME). (This variable is also available with a NTLM authentication)


Now with that information I'm trying to develop an automatic login. Theoretically is not that hard, I have to check the username on a preDispatch function and then if the user exist in useresponse, connect him.

Otherwise, if the user is not yet in useresponse I would do a LDAP query with the username connected, retrieves is informations and then create an account and connect.


So theoretically is simple but I have a lot of trouble to do it technically. I don't know the Zend framework and it kind of complicated to understand all the logic.


First of all I want to disable the normal login and registration options, i would let the login page option if there is issues with the automatic sso . I would like to disable the options in the login form, but I can't find how, I don't want just a css option. I would like to disable the option in the top bar of the login page and just let the sso form.


I have been able to disable the native authentication with this otpion (found in the onelogin Sso Code)

Singular_Core::_('settings')->changeSetting('sso_native_auth_disabled', '1');

But it disable all the login page for me


Then, I will have to write the logic. I created a module and in the handlers (events.php) I wrote a preDispatch function.

  1. $loggedUser = Singular_Runtime::extract('loggedUser');
  2. if ($loggedUser->isGuest()){
  3. $front = Zend_Controller_Front::getInstance();
  4. $request = $front->getRequest();
  5. $params = $request->getParams();
  6. if($params['action'] !="MyAUTOSsoLOGIC" ){
  7. Zend_Controller_Action_HelperBroker::getStaticHelper('redirector')->gotoUrlAndExit("MyAUTOSsoLOGIC");
  8. }
  9. }


My idea would be to put the logic of my autoSSo in a service (as the staff advised me) and call it from the preDispatch function.


I will keep you in touch and share my work if I manage to do all those things.


And thanks to the staff for all the support ;)


Robin

Replies (6)

photo
1

Hello Robin,

In upcoming new version we'll make available showing SSO tab in the form by going to following URL /login/method/ldap/redirect/reset

I'm sure other users will benefit from what you are doing... In fact, in new version, you'll be able to put the link to Login to LDAP and with your module replace standard links and hide all other forms not required leaving just LDAP form with the help of js.

photo
1

Okay great Stas, thanks ;)


For the moment I finally found a way to disable normal login.

I modified the header.phtml in my theme. I forced the ldap login form by adding the line : $this->showPopup = "ldap"

And then I deleted all the other forms buttons (login, register) in the html elements "b-popup-tabs"

It does the jobs and I didn't have to modify the modules.

photo
1

Glad it worked for you :)

Have a great day!

photo
1

So, I finally succeed to implement an automatic SSO. Here quickly what I did :


1 - Create a custom Module

=> in Module.php add in the installation process a query for adding a field "username" in the user table. This field will contain the AD/LDAP username.

  1. $sql = "ALTER TABLE `{$this->_tablePrefix}users` ADD `username` VARCHAR(32) NULL AFTER `id`";
  2. try{
  3. $this->_adapter->query($sql);
  4. }

You have to add this "username" in the system model for adding user, also in the cookies and so on.


2 - Create a service in your module :

In this service I wrote a function which check if there is an user registered in the $_SERVER variable. If yes, check if the username exist in the useresponse DB and connect if yes. Otherwise if the user do not exist (first time), interrogate the ldap to retrieve user information and create new user.

I wrote a function like that :

  1. public static function SSOAuto (){
  2. if(isset($_SERVER['AUTH_USER']) && !empty($_SERVER['AUTH_USER'])){
  3. $username = explode("\\",$_SERVER['AUTH_USER']);
  4. $username = $username[1];
  5. }
  6. else
  7. Zend_Controller_Action_HelperBroker::getStaticHelper('redirector')->gotoUrlAndExit("login");
  8. $usersDb = Singular_Loader::get("System_Model_DbTable_Users");
  9. $userObject = $usersDb->findByUsername($username);//has to be create, it's kind of the same than findByEmail
  10. if ($userObject instanceof System_Model_User) {
  11. self::_loginByUsername($username); //has to be created
  12. }
  13. else{
  14. $config = self::_setup($username);
  15. $sso_ldap_map_uuid = Singular_Core::_('settings')->getSetting('sso_ldap_map_uuid');
  16. $search = array('filter' => "({$sso_ldap_map_uuid}={$username})");
  17. $ldap = new Zend_Ldap($config);
  18. try {
  19. //service account with AD read rights
  20. $ldap->bind($config['username'],$config['password'], Zend_Ldap::SEARCH_SCOPE_ONE);
  21. $ldapUser = $ldap->search($search,$config['baseDn'])->toArray();
  22. /* Successful auth */
  23. $cookieData = array();
  24. //add username in the cookie
  25. $cookieData['username'] = $username ;
  26. $cookieData['email'] = (isset($ldapUser[0]['mail']))
  27. ? $ldapUser[0]['mail'][0]
  28. : "{$data['username']}@localhost";
  29. if (isset($ldapUser[0]['sn']) && (isset($ldapUser[0]['gn']))) {
  30. $cookieData['fullname'] = "{$ldapUser[0]['gn'][0]} {$ldapUser[0]['sn'][0]}";
  31. } elseif (isset($ldapUser[0]['sn']) && (isset($ldapUser[0]['givenname']))) {
  32. $cookieData['fullname'] = "{$ldapUser[0]['givenname'][0]} {$ldapUser[0]['sn'][0]}";
  33. } else {
  34. $cookieData['fullname'] = ucfirst($data['username']);
  35. }
  36. setcookie("ldap_user", Zend_Json::encode($cookieData), null, "/");
  37. $user = new System_Model_User();
  38. $register = $user->register(array(
  39. 'full_name' => $cookieData['fullname'],
  40. 'email' => $cookieData['email'],
  41. 'username' =>$cookieData['username']
  42. ));
  43. if ($register) {
  44. System_Service_Auth::loginByEmail($user->email);
  45. Zend_Controller_Action_HelperBroker::getStaticHelper('redirector')->setGotoRoute(array(), 'default');
  46. return;
  47. }
  48. } catch (Zend_Ldap_Exception $exception) {
  49. Zend_Controller_Action_HelperBroker::getStaticHelper('redirector')->gotoUrlAndExit("login");
  50. }
  51. }
  52. }


3 => Create a handler in the module, with a predispatch function in which you call the sso function if the user is not logged

  1. public function onPreDispatch ($request)
  2. {
  3. $loggedUser = Singular_Runtime::extract('loggedUser');
  4. if ($loggedUser->isGuest()){
  5. $front = Zend_Controller_Front::getInstance();
  6. $request = $front->getRequest();
  7. $params = $request->getParams();
  8. if($params['action'] !="login" ){
  9. SsoModule_Service_SSOservice::SsoAuto();
  10. }
  11. }
  12. }


Some improvement could be done, but for the moment it works .


Robin

photo
1

hi,

Have a question on SSO. As per the pricing page, it is indicated as user login into Useresponse and then it logins to other application.

However, our case is that user will login to our internal applications, which in turn should login into useresponse. Is this supported as part of the corporate edition? Can you please confirm.


Looking at the above thread it looks like we need to do the SSO in the way I had described above. Will be good if you can confirm the same too.


thanks

Srinivasan S

photo
1

Srinivasan,

SSO works both ways, so when you login in your application, you'll be automatically logged in UseResponse. More details

Replies have been locked on this page!