2010-10-20 78 views

回答

1

這似乎是a bug of the Shibboleth module,所以登錄'事件'確實不是由它引發的(在Drupal中,它不會調用hook_user()$op = 'login')。

Looking at the Shibboleth code,登錄似乎在hook_init()執行的情況發生:

/** 
* Create a new user based on informations from the Shibboleth handler if it's necessary or log in. 
*/ 
function shib_auth_init() { 
    global $user; 

    $unameVar = variable_get('shib_auth_username_variable', 'REMOTE_USER'); 
    $umailVar = variable_get('shib_auth_username_email', 'HTTP_SHIB_MAIL'); 

    // If 
    // - The user isn't logged in 
    // - There is Shibboleth authentication in the background 
    // - The settings are fine and there has been a valid username setted up 
    // - The settings are fine and there has been a valid user email address setted up 
    if (!$user->uid && $_SERVER['HTTP_SHIB_IDENTITY_PROVIDER']) { 
    if ($_SERVER[$unameVar] && $_SERVER[$umailVar]) { 
     user_external_login_register($_SERVER[$unameVar], "shib_auth"); 
    } 
    else { 
     drupal_set_message(t("Username or e-mail address is missing. Maybe the Shibboleth configuration is not perfect."),"error"); 
    } 
    } 
    if ($user->uid && $_SERVER['HTTP_SHIB_IDENTITY_PROVIDER']) { 
    $account = user_save($user,array('mail' => $_SERVER[$umailVar])); 
    // Terminate if an error occured during user_save(). 
    if (!$account) { 
     drupal_set_message(t("Error saving user account."), 'error'); 
     return; 
    } 
    $user = $account; 
    } 
} // function shib_auth_init() 

所以你需要修補這個和,並確保user_module_invoke()被調用。這樣做的標準方法是調用user_authenticate_finalize()成功登錄之後(這將反過來調用user_module_invoke()),所以你要補充的是,user_external_login_register()調用之後:

[...] 
    if ($_SERVER[$unameVar] && $_SERVER[$umailVar]) { 
     user_external_login_register($_SERVER[$unameVar], "shib_auth"); 
     // Do we have a logged in user now? 
     if ($user->uid) { 
     // Yes, ensure watchdog logging and proper invocation of hook_user 
     // NOTE: We pass an empty array, as no form submit was involved here, 
     // but we could also pass an array with 'unameVar' and 'umailVar', 
     // as they would be the closest substitute. 
     user_authenticate_finalize(array()); 
     } 
    } 
    [...] 

注:未經測試的代碼,提防錯別字和其他愚蠢的疏忽;)

您應該結束了這樣做,你可能要提交一個補丁上面鏈接錯誤報告。 (僅當它的工作原理,很明顯;)

0

在其中的Drupal加載模塊的順序是在這些情況下非常重要。您需要設置規則,以便在驗證模塊之後加載它。例如,對於ldap_integration

mysql> UPDATE system SET weight=20 WHERE name="rules"; 
mysql> UPDATE system SET weight=20 WHERE name="rules_forms"; 
mysql> UPDATE system SET weight=0 WHERE name="ldapauth"; 

「20」是比無論你的身份驗證模塊更大的任意數。

+0

恕我直言,執行(或加載)順序在這裏不相關,因爲根本沒有調用鉤子! (這個命令只是相關的,如果他想在另一個模塊實現同一個鉤子之後做出反應,但是在這種情況下,首先沒有任何反應) – 2010-10-20 20:53:36

0

Drupal的運行hooks,這意味着模塊獲得運行一段代碼的機會。例如。在登錄時調用hook_user。

太多的時候,模塊將調用一個drupal_goto()這樣鉤的內部。這會打破。 Drupal_goto會殺死所有的東西,發送重定向頭,然後死掉應用程序。沒有其他的鉤子會跑。

  1. 掛鉤不應該調用drupal_goto(),die()或其他這樣的破壞函數。但是由於沒有什麼能夠阻止人們打破這個規則,所以人們(模塊)會打破它。
  2. 出於同樣的原因,form_alter不應該調用goto,死亡等等。

您可以通過安裝devel模塊並切換設置「show redirects」找到任何「非法」goto's,您會看到例如, sibbletooth在它不應該有的地方引用了一個重定向。