Single Sign On for Your Members


Published on

Krystee Dryer's Single Sign On for your Members presentation from the 2012 Drupal Capital Camp in Washington DC

In this session, we will be cracking open our process to develop custom SSO modules with a CRM or membership database and Drupal.

This session will introduce how to:
• Connect with the third-party service
• Insert a custom validation function in the login process
• Use tools to make the development process easier
• Save the information from the application to the Drupal user
• Handle other integration to the SSO (edit my profile, forgot password, etc).
• Manage advanced development like adding members to organic groups programmatically

You can also sneak a peak at our own custom SSO module in development that will allow you to do all of the above easily in the configuration settings.

Published in: Technology, Design
1 Comment
  • This was a great presentation. I attended and reviewed the slides with great interest.
    One question I have -- on slide 18/25, I'm wondering where the body array was constructed. Were you working with the services module, using it to build objects from the WSDL, or was all SOAP work done custom in your module?
    Can you share some of the code you used to construct your SOAP calls?
    Thanks again!
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Single Sign On for Your Members

  1. 1. Single Sign On foryour MembersJuly 27, 2012Krystee Dryer@krysgeekCapital Camp
  2. 2. Scope• Will there be one login form to authenticate both systems (i.e. single sign on)?• What roles will users be assigned in the CMS and AMS?• Are there other types of groups or membership types that have special functionality?• Will users be able to edit their profile?• Will users be able to sign up for or renew their memberships online?• Will there be online event registration?• Will there be e-commerce functionality (shopping cart, payment processors, etc)?• Will the CMS have role-oriented content? Balance Interactive Inc.
  3. 3. Integration Options• Does the CMS have an existing module/plugin available for the AMS integration?• Is there a web service available?• Are we authenticating against a remote database?• What other options are available for single sign on?• Is there a development installation of the AMS for testing purposes? Balance Interactive Inc.
  4. 4. Authentication Scenarios• Will the user login to the CMS (which will authenticate against the AMS and return with the necessary information to the CMS) or will the user login to the AMS (and then add login token to their user session in the CMS)?• How do we provide the reverse authentication scenario if the login is performed in a non-standard way?• What information is available to the CMS (from the AMS) to use for personalization? Balance Interactive Inc.
  5. 5. User Stories• Once all of the decisions have been made, we develop our user stories to cover all scenarios of user interaction between the CMS and AMS.• Those user stories are used in our build phase and translated into our testing plan with test users to fit each story.• Once build is done for each user story, our QA team tests each scenario and reports findings and any issues found. Balance Interactive Inc.
  6. 6. SSO Case Study and Example Code • Clients has a complex membership structure that includes both roles and committees. • The web site should have membership based access and content depending on their roles and committees. • All of the info should be stored in their AMS (events, publications, membership activity, etc.) • They want to use the registration, edit your profile, and forgot passwords in the AMS (not through Drupal). • They want so login in one place and go back and forth between the CMS and AMS. • They want some limited personalization on the site (Welcome, Name message). • Balance Interactive Inc. a extensive API and web services available. AMS had
  7. 7. Custom SSO Module – Install Functions function netforumod_auth_new_fields() { return array( Since the client cst_name => array( wanted description => t(The customer name), type => varchar, personalization, we length => 500, created some new ), not null => FALSE, fields in the user table cst_id => array( to store this info with description => t(The customer ID), type => varchar, the user information. length => 10, not null => FALSE, ), cst_web_token => array( description => t(The SSO Token), type => varchar, length => 400, not null => FALSE, ), ); } Balance Interactive Inc.
  8. 8. Custom SSO Module – Install Functions /** Since our module is * Implements hook_schema_alter(). */ modifying the function netforumod_auth_schema_alter(&$schema) { database structure of $schema[users][fields] = another module, array_merge($schema[users][fields], netforumod_aut h_new_fields()); hook_schema_alter() } is used update the /** default $schema and * Implements hook_install(). to take our changes */ into account. function netforumod_auth_install() { foreach (netforumod_auth_new_fields() as $name => $field) { db_add_field(users, $name, $field); The install function is } adding the new fields } to the user database. Balance Interactive Inc.
  9. 9. Custom SSO Module – Admin Functions Use the Drupal Form $form[authentication][netforumod_auth_ssourl] = array( #type => textfield, API to create a #title => t(netFORUM OnDemand SSO Web Service URL), #default_value => variable_get(netforumod_auth_ssourl, NULL), settings page used by #description => t(WDSL Web Service URL for the netFORUM the admin to enter in SSO.), ); the web service url(s) $form[authentication][netforumod_auth_xweburl] = array( #type => textfield, and authentication #title => t(netFORUM OnDemand xWeb Service URL), #default_value => variable_get(netforumod_auth_xweburl, NULL), credentials. #description => t(WDSL Web Service URL for the netFORUM xWeb.), ); $form[authentication][netforumod_auth_username] = array( #type => textfield, #title => t(Username for netFORUM), #default_value => variable_get(netforumod_auth_username, NULL), #description => t(Password for the netFORUM web service.), ); $form[authentication][netforumod_auth_pass] = array( #type => textfield, #title => t(Password for netFORUM), #default_value => variable_get(netforumod_auth_pass, NULL), #description => t(Password for the netFORUM web service.), Balance Interactive Inc. );
  10. 10. Custom SSO Module – Admin Functions Since we needed to foreach (user_roles(TRUE, NULL) as $key => $var) { $form[roles][netforumod_auth_role_val_ . $key] = bring over the roles array( form the AMS into #type’ => textarea, Drupal, we wanted a #title => t(netFORUM Membership Name to map to Drupal role - @var, array(@var => $var)), way to map the role #default_value => information returned variable_get(netforumod_auth_role_val_ . $key, ), by the web service to #description => t(List of Avectra Membership Types. Enter one netFORUM OnDemand Product Code the roles we set in per line.) Drupal. ); } Balance Interactive Inc.
  11. 11. Custom SSO Module – Admin Functions foreach (og_get_all_group($states = To handle the array(OG_STATE_ACTIVE), $options = array(TRUE, FALSE)) as $key => $var) { committee $form[og][netforumod_auth_group_val_ . $key] = functionality, we used array( #type’ => textfield, the Organic Groups #title => t(netFORUM Product Code to map to module and created a Organic Group ID - @var, array(@var=> $var)), #default_value => group for each variable_get(netforumod_auth_group_val_ . $key, ), ); committee. The } groups had their own content and membership base. We needed some variables to handle the mapping of the AMS committees to the Balance Interactive Inc. organic groups.
  12. 12. Custom SSO Module – Admin Functions We also added a way to $form[exempt][netforumod_auth_exempt] = array( #type => textarea, exempt user(s) from the #title => t(Exempt users), SSO process for testing #default_value => purposes or content variable_get(netforumod_auth_exempt, ), #description => t(List of Drupal User IDs on this entering temps that are site to exempt from netFORUM OnDemand not in the AMS database. authentication. Enter one user ID per line. These users will login using their Drupal credentials, and can have roles in addition to "authenticated user". The user ID of a user can be determined by visiting !link and clicking on the "edit" link for each user. The user ID will then be visible in the URL in the format /user/##/edit where ## is the user ID.’), ); Balance Interactive Inc.
  13. 13. Custom SSO Module – Admin Functions The other functions in the file were some validation functions of the web service urls, and some variables to indicate if we are overriding the normal Drupal links for registering, forgot password, and edit profile. Balance Interactive Inc.
  14. 14. Custom SSO Module – Module Functions /** We used * Implements hook_menu_alter(). hook_menu_alter() to */ function netforumod_auth_menu_alter(&$items) { override the normal // Disable password reset page if indicated in module settings. Drupal links for: $disable_pass_link = variable_get(netforumod_auth_sso_var_ForgotPass, 0); • register, if ($disable_pass_link) { unset($items[user/password]); • forgot password } • edit profile // Disable edit my profile page if indicated in module settings. $disable_profile_link = variable_get(netforumod_auth_sso_var_Profile, 0); global $user; if ($disable_profile_link) { $items[user/%user_category/edit][type] = (if the settings page MENU_CALLBACK; $items[user/%user][type] = MENU_CALLBACK; indicated that they } } should be removed or overridden). Balance Interactive Inc.
  15. 15. Custom SSO Module – Module Functions • We used //** * Implements hook_form_alter(). hook_form_alter() */ on the Drupal login function netforumod_auth_form_alter(&$form, &$form_state, $form_id) { form. if ($form_id == user_login_block || $form_id == user_login || • The links on the form $form_id == user_login_form) { were overridden or removed if necessary. //Add all the logic around the Drupal links in the login form and override if necessary • We add our custom validation function to // Overwrite Drupals validation handler and substitute a the normal Drupal custom one. validation handler. $form[#validate] = array(netforumod_auth_login_validate); } } Balance Interactive Inc.
  16. 16. Custom SSO Module – Module FunctionsWe tested if user was function netforumod_auth_login_validate(&$form, &$form_state) { // Check if user is already in exempt user. If so,just use the normal // Grab username from form input.Drupal login process. If $res = db_query("SELECT uid FROM {users} WHERE name = :name", array(:name => $username));not, go through the if ($res && $res->rowCount() > 0 && $obj = $res->fetchObject()) {custom authentication } $uid = $obj->uid;function. // Find out if the user is in the list of exempt users. // Make sure that user 1 has been added to this list and that user 0 is not added to the list. if (!in_array($uid, $list)) { $auth_rtn = netforumod_auth_authenticate($form_state[values], $uid, $formstate, $form); if (!$auth_rtn) { // If unsuccessful login, redirect to user login page. unset($_REQUEST[destination], $_REQUEST[edit][destination]); drupal_set_message(t("Sorry, unrecognized username or password"), error); drupal_goto(user); } } else { Balance Interactive user_login_authenticate_validate($form, $form_state); Inc. } }
  17. 17. Custom SSO Module – Module Functions Call two different web services: #1 – send our admin credentials into their system and return an SSO token (if authenticated). #2 – SSO web services that we sent our returned SSO token and sent in the user’s credentials and returned the authentication variable (true or false) and user object (roles, committees, company id, etc). We also had to send in the company id and return the committees and roles the company owned and apply them to the user. Balance Interactive Inc.
  18. 18. Custom SSO Module – Module Functions// #4 CheckEwebUsertry { $headerbody = array(Token => $token[3]); $header = new SoapHeader($ns, "AuthorizationToken", $headerbody); $client->__setSoapHeaders($header); $parameters = array( szEmail => $username, szPassword => $pass, ); $response = $client->CheckEWebUser($parameters); $result = xml2array($client->__getLastResponse()); $memberships = array(); $token[4] = $result[soap:Envelope][soap:Header][AuthorizationToken][Token]; $cst_key = $result[soap:Envelope][soap:Body][CheckEWebUserResponse][CheckEWebUserResult’][Result][cst_key]; $cst_id = $result[soap:Envelope][soap:Body][CheckEWebUserResponse][CheckEWebUserResult’][Result][cst_id]; $name = $result[soap:Envelope][soap:Body][CheckEWebUserResponse][CheckEWebUserResult’][Result][cst_name_cp]; $memberships[] =$result[soap:Envelope][soap:Body][CheckEWebUserResponse][CheckEWebUserResult’][Result][ProductCode];} catch (Exception $e) { $message = $e->getMessage(); drupal_set_message(t("Cannot establish a connection the membership database. Please contact the site administrator")); return FALSE; Balance Interactive Inc.}
  19. 19. Custom SSO Module – Module Functions We have grabbed all of the roles from the user object returned from the web service and now call our mapping to Drupal roles and assign them to the $newroles array.$memberships = array_filter(array_unique($memberships));$roles = $memberships;// Check if member type matches.$drupalroles = user_roles(TRUE, NULL);// Check if member type matches.foreach ($drupalroles as $key => $var) { if (variable_get(netforumod_auth_role_val_ . $key, NULL)) { foreach ($roles as $rolekey => $rolevar) { if (!in_array($rolevar, netforumod_auth_textarea_to_array(variable_get(netforumod_auth_role_val_ . $key, NULL)))) { $newroles[$key] = TRUE; } } } } Balance Interactive Inc.$newroles[DRUPAL_AUTHENTICATED_RID] = TRUE;
  20. 20. Custom SSO Module – Module FunctionsWe have all of the information we need and now put it into an arraythat we will send to Drupal to save a new user or update an existingone. $mail = $username; //Update the user table with all relevant information $update = array( mail => $mail, name => $username, pass => $pass, status => 1, cst_key => $cst_key, cst_ssotoken => $cst_ssotoken, cst_id => $cst_id, cst_web_password => $name, init => $username, roles => $newroles, access => REQUEST_TIME, Balance Interactive Inc. );
  21. 21. Custom SSO Module – Module Functions We have all of the information we need and now put it into an array that we will send to Drupal to save a new user or update an existing one.if($uid) { $account = user_load($uid); watchdog(user, Updated user %user %uid using module %module., array(%user => $name, %uid => $uid,%module => netforumod_auth), WATCHDOG_NOTICE, l(t(edit), user/ . $account->uid . /edit)); $account = user_save($account, $update);} else { $account = user_save(NULL, $update); watchdog(user, New external user: %user using module %module., array(%user => $name, %module =>netforumod_auth), WATCHDOG_NOTICE, l(t(edit), user/ . $account->uid . /edit)); Balance Interactive Inc.}
  22. 22. Custom SSO Module – Module Functions We have all of the information we need and now put it into an array that we will send to Drupal to save a new user or update an existing one.//set group memberships$account = netforumod_auth_set_groups($memberships, $account); watchdog(user, User id = %uid using module %module., array(%uid => $uid, %module =>netforumod_auth), WATCHDOG_NOTICE, l(t(edit), user/ . $account->uid . /edit));user_set_authmaps($account, array("authname_netforumod_auth" => $username));user_external_login_register($username, netforumod_auth);$form_state[uid] = $account->uid;$form[#submit] = array();// User authenticated and was updated in Drupal - login success.return TRUE; Balance Interactive Inc.
  23. 23. Final ConsiderationsWe still need to address passing through the logged instate to the AMS pages. • The AMS provided a SSO token that we saved into the database. This token was appended to the url when linked back to the AMS pages. • When the user logged out the token on the AMS side was destroyed.API’s from the AMS were used to call and return a listcurrent events and products and display them on theDrupal site. All links went back to the AMS pages with theSSO token appended (if logged in). Balance Interactive Inc.
  24. 24. SSO Wrap Up• Create your admin pages to enter in your connection variables, user credentials, role mapping.• Add an exempt user function to allow user story testing without having to enter the users in the AMS database.• Add some functionality to override or remove the Drupal user links if needed.• Use hook_form_alter() to add a custom authentication function to the login process and call the custom authentication function if user is not exempt.• If user is not exempt, call your web services using the saved variables and return the user object.• Compare the roles returned in the user object and map them to the Drupal roles and save/create the user. Log the user in to Drupal.• Balance Interactive Inc.
  25. 25. QUESTIONS?Contact us:krystee.dryer@balanceinteractive.comFollow: @krysgeekDrupal username: krysgeekMore Info:Balance Blog: Interactive Inc.