Issue 1:
If the user has already logged in using the IdP to access another service and then visits the drupal site using this plugin he/she is required to click the link to authenticate. With a SSO the site should automatically look for the cookie for the user and signon without requiring the signon link to be clicked.

Issue 2:
I can't get the signout to use the SingleSignLogout on my IdP. Seems to be some bug that won't let me redirect to there. So it kills the session (no_so) and stays on the site even though the simplesamlphp meta has the correct signout in it.

Comments

geekwisdom’s picture

Assigned: Unassigned » geekwisdom

Issue #1 - I see no way to meet your expectations on this one. The operative phrase is "another service", which equates to "another SAML service provider"; presumably on another server. How is the second SP to know that the user is authenticated at an IdP already unless the user initiates SSO from either the SP (SP-initiated SSO) or the IdP (IdP-initiated SSO)? Either way the user has to do something. Even if they have an active session on the IdP and a different SP, so long as the session on the second SP isn't linked to the session on the IdP the user is going to have to initiate the connection. This is especially true if the second SP has trust relationships with more than one IdP, in which case it needs to ask the following question of the user, "Which IdP is going to vouch for your identity?" or worded another way, "Where are you from?"

Issue #2 - Does Single Logout work when you "Test Authentication Sources" using SimpleSAMLphp?

doublejosh’s picture

#1) If only using one outside SSO identity source is it not possible to log a user in without visiting a specific URL?
I thought this module was able to pick up on this and login/register/authenticate at any page.

#2) Ever fix the logout problem?

geekwisdom’s picture

@doublejosh, #1 is not an issue with the simplesamlphp_auth module. The module depends on a local SimpleSAMLphp instance. It's this SimpleSAMLphp instance that implements SAML and maintains the SAML Service Provider session. The simplesamlphp_auth module bridges the SAML SP session into a Drupal session for the user. However, unless the local instance SimpleSAMLphp SP has an active session for the user the simplesamlphp_auth module can't know the user is logged in anywhere.

The only scenerio where the user is automatically logged into Drupal based on an active SAML SP session is if another PHP application is depending on the same instance of SimpleSAMLphp and the user has already established a session with the SimpleSAMLphp SP in order to access that app. In this case the user would be automatically logged into Drupal.

Otherwise, something has to happen to tie the user's active (or soon to be active) session with an IdP to the SAML SP that services Drupal in order for the simplesamlphp_auth module to bridge the sessions.

There could be a way to make this work the way you want assuming:
a) You have your SimpleSAMLphp SP setup to communicate with a single IdP (e.g., 'idp' => 'someidp.example.org' in simplesamlphp/config/authsources.php)
b) You tweak Drupal so that when authentication is required the user is automatically redirected to https://www.example.org/drupal/saml_login

The module does not do #b automatically because some administrators allow users to log in with local Drupal accounts in addition to SAML authentication sources.

With regard to #2 (logout issues) I suspect this was a SimpleSAMLphp configuration issue for @charlie_love, which could be easily tested by using the built-in "Test Authentication Sources" feature of SimpleSAMLphp.

doublejosh’s picture

Thanks for the quick response and great feedback!
Sounds like I'll just need to tweak our authsources.php to work with our auth.mydomain.com

doublejosh’s picture

Creating a submodule to auto-login users even on cached pages.

doublejosh’s picture

Here's a way to auto-login folks even on cached pages when used in combination with the provisional Dynamic Cache module.

Set this up as a sub or custom module...

// Allow simpleSAMLphp SSO login attempt even on cached pages!
function simplesamlphp_authboot_boot() {

    // Recreate beginning of simplesamlphp_auth_init().
    global $user;
    global $_simplesamlphp_auth_as;

    $basedir = variable_get('simplesamlphp_auth_installdir', '/var/simplesamlphp');
    include_once($basedir . '/lib/_autoload.php');
    
    $_simplesamlphp_auth_as = new SimpleSAML_Auth_Simple(variable_get('simplesamlphp_auth_authsource', 'default-sp'));
        
    // Little sanity protection so bad simpleSAML settings won't lock your site :)
    if($_simplesamlphp_auth_as) {
    
        // If not logged into Drupal.
        if ($user->uid == 0) {
            
            // If SSO cookie is present.
            if((isset($_COOKIE['MY-COOKIE-ID'])) && ($_COOKIE['MY-COOKIE-ID'] != "")) {
                // Login to SAML via the SSO cookie.
                $_simplesamlphp_auth_as->requireAuth();
                // Allow the simplesamlphp_auth_init() to login the user.
                $GLOBALS['conf']['cache'] = CACHE_DISABLED;
                // Give all modules a change to run exit hooks.
                module_invoke('all','exit');
                // Avoid single cached page view. FYI: drupal_goto() is not available yet.
                header('Location: '. request_uri(), TRUE, 301);
    
            } else {
                // Nevermind, totally anonymous user.
                return; // Keep serving cached page.
            }

        } else {
            // Logged into Drupal
        }

    } else {
        watchdog('simplesamlphp_authboot_boot',
            'Ut oh! simplesamlphp_authboot_boot can not run without simplesamlphp_auth setup correctly.');
    }
}
doublejosh’s picture

Looking to making this a part of the module for D7. Interested in this being a submodule with options within the admin UI?
Really want to get away from my forked version of simplesamlphp_auth!
Assume others want this cache bypass autologin.

doublejosh’s picture

Don't want to hijack this issue.
But I've created a submodule to accomplish logging in when a configurable cookie is present for the user. You don't have to choose auto-login, but it at least allows bypassing site cache to get the user able to be logged in if they should be. But you can also turn on auto-login if you'd like to automatically call the simpleSAML service... which I do.

Implemented as a submodule since it requires a boot function and some folks may not want it.
Also, had to split off an inc file because the boot function need to borrow a "helper" function from the main module.
(This patch includes new files.)

doublejosh’s picture

Sorry ran incorrectly. Adding files in git diffs is a little touchy. Needed to use "git add -N" (notes)

...and I named the new file wrong. Sorry!

doublejosh’s picture

Title: Sign On/Sign Out Issues » Auto sign in feature and single sign out problem
doublejosh’s picture

Status: Active » Needs review
doublejosh’s picture

Annoying. Found that these patches which include new files don't work with a normal git apply command.
Had to use patch -p1 < filename.patch and had to place it in the project root.
Maybe there's a param to allow new files, but I couldn't find it.

doublejosh’s picture

Status: Needs review » Needs work
geekwisdom’s picture

I'm going to need to do a review of this. If it's incorporated it will likely go into the 7.x-2.x branch.

doublejosh’s picture

Also adding auto-logout (when cookie is destroyed by SSO system elsewhere).
Not sure where to post that code.

doublejosh’s picture

Added the setting within the boot submodule since that's what already houses the SSO cookie concept.
Then added a test for missing or blank within the main module.

Use case is when a number of systems (or another SSO master) needs to log users out of Drupal but the SAML session remains because true single-logout-has not been implemented systemwide.

doublejosh’s picture

I've found an issue with context.
Blocks which use Role as a Condition do not recognize a user as NOT anonymous during the first page load when cache is bypassed in this manner. For some reason the following code is not Context compliant...

...
      // We want to restart uncached so simpleSAMLphp_auth proper can take over.
      header('X-Drupal-Cache: MISS');
      ob_start();
      // Continue the bootstrap process.
      drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
      // Execute the page callback and exit.
      menu_execute_active_handler();
      exit;
...

Any thoughts?

doublejosh’s picture

Partially solved my problem by reducing the module weight of simpleSAMLphp_auth. I urge you to test this to no-end, as various registration modules' weight is fragile with regard to submit and validation handlers.

Still stuck with an issue though. During the auto-provision step --in the first page load-- there is a failure of access checking, so all "node blocks" and menu blocks will not show up. Everything is fine on subsequent loads. (using context for all blocks, it's weight is after).

Also here's a VERY important update to the above PHP for the boot process. Otherwise it will cache the page in the editor state!

      header('X-Drupal-Cache: MISS');
      drupal_page_is_cacheable(FALSE);
      ob_start();
      drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
      menu_execute_active_handler();
      exit;
doublejosh’s picture

Around this with a drupal_goto() call after the user creation. Not solving the root problem, and it's possible something in the stack could get missed if you use a number of user registration modules steps. But seems to work for me with testing.

Added a goto within the external reg area of simplesamlphp_auth_init()...


function simplesamlphp_auth_init() {
// ...
        if (!$ext_user) {
// ...
            drupal_set_message(t("Welcome. Since this is your first time logging in... blah blah."), 'status');
            global $base_url; // << new line.
            drupal_goto($base_url . '?ssoreg=success'); // << new line.
// ...

Hope that's helpful.

colan’s picture

Title: Auto sign in feature and single sign out problem » Enable automatic logins for IDP users
Version: 7.x-1.2 » 7.x-2.x-dev
Assigned: geekwisdom » Unassigned

An up-to-date patch for the work above would be nice. :)

doublejosh’s picture

I'm kinda forked.

petethebloke’s picture

Is there a simple way to do this? I'll briefly explain my problem.

Site_1 is an idp
Site_2 is an SP

Site_2 stores files that need to be accessed from site_1 after authentication. At the moment a user clicks the link in site_1 and gets the site_2 login page. If he clicks "federated login" everything works seamlessly from that moment onwards.

How do I bypass that first click on "federated login"?

petethebloke’s picture

Following on from my question above. The solution was kindly suggested by xamanu

https://drupal.org/project/r4032login

binaryatwork’s picture

Issue summary: View changes

I patched my Drupal with attached patches but the configuration "simplesamlphp_auth_cachebypass" and "simplesamlphp_auth_autologin" do not show up in SimpleSamlPhp_Auth configuration screen.

Are the patches still valid for Drupal 7.5?

Thank you.

binaryatwork’s picture

I use the module, r4032login, and it works well for automatic saml sos login.

Thanks

brian-c’s picture

Thanks to @doublejosh for the patch above. We ran into Issue 1 described in the original ticket. When a user would sign in via our idP, they would be returned to a cached version of the page they logged in from, with no visual indication that they were logged in (i.e. their username and profile options did not display). Clearing the site cache at this point would reveal the user's logged in state, as would clicking the sign in link again (though without needing to reenter user credentials--the session would authenticate automatically).

The suggestions for r4032login as a fix are really only sidestepping the problem by redirecting you to the login when you encounter user-restricted content, so @doublejosh's patch was really what we needed.

Attached is that patch rerolled for 7.x-2.x-dev, with one minor addition.

We found issues with both Drupal's cache and Varnish where multiple instances of the page were being returned--as you scrolled to the bottom of the page you would either see an entirely new copy of the page (or two or three copies) or a bunch of bad characters, depending on the cache settings. Acquia helped us out and found we needed a drupal_exit() at the end of the if ($boot_cookie_present) condition.

manningpete’s picture

Status: Needs work » Needs review
djdevin’s picture

@Brian C, for that issue have a look at http://drupal.org/project/dynamic_cache which would address both your cache issues and also that issue with the duplicate content. You can detect something in hook_boot, and then dynamic_cache will ensure that the Drupal cache doesn't kick in. Would save some code in the patch.

We've used it before many times in situations like this where we have to bust the page cache in order to do something like SSO.

pcambra’s picture

Just adding a comment in the lines of #23 and #25, using https://drupal.org/project/r4032login and redirecting the 403 page to whatever the simplesamlphp has as login and disabling the error message from r4032login works for my use case. Users end up where they expected without having to login again or getting a 403.

These are the settings:

  variable_set('r4032login_user_login_path', 'saml_login');
  variable_set('r4032login_access_denied_message', '');
brian-c’s picture

The r4032login is fine when a user is encountering a 403, but our use case wasn't for a restricted page, but any page at all--users who had authenticated via SSO were returned to the website but couldn't see the admin toolbar. If I understand r4032login correctly, if the path they were landing on wasn't restricted it wouldn't do anything here.

The Dynamic Cache option looks better, though it's still in RC and isn't covered by the security advisory policy, fwiw.

pcambra’s picture

Can confirm the issue with the cache and the r4032login, sometimes the users will be just redirected to the homepage when not logged in and try to access restricted content, when they should be taken to the login and then to the content that they wanted to see.
I don't really want to change cache rules as there are just too many things involved there, one "quick and dirty" solution for me is to replace the user_logout bit by a redirection, so in the .module file:

  // Logs out user if not SAML authenticated and not allowed default login.
  if (!$_simplesamlphp_auth_as->isAuthenticated() && !$user_allowed_default_login) {
    module_load_include('pages.inc', 'user');
    user_logout();
  }

I am not trying this instead:

  // Logs out user if not SAML authenticated and not allowed default login.
  if (!$_simplesamlphp_auth_as->isAuthenticated() && !$user_allowed_default_login) {
    module_load_include('pages.inc', 'user');
    user_logout_current_user();
    drupal_access_denied();
  }

The drupal_access_denied() call will kick the r4032login module and the behavior seems as expected without killing the cache,.

This seems fine for my case but I haven't attached a patch because it might not be the usual case, as I have many patches applied to this module, and this only covers the case of local logout with no other actions in hook_user_logout.

botanic_spark’s picture

Anyone tried this on Drupal 8?