2

私のインストールでは、ユーザーは Shibboleth [1] でログインしますが、「ユーザーがログインしました」イベントで実行されるように設定したルール [2] は実行されません。

一方、通常の Drupal の方法で管理者としてログインすると、ルールが実行されます。

これは、外部ログイン イベントがまったく処理されないということですか?

これを克服する方法はありますか?

[1] http://drupal.org/project/shib_auth

[2] http://drupal.org/project/rules

4

3 に答える 3

1

これは Shibboleth モジュールのバグのようです。そのため、実際にはログイン 'イベント' は発生しません (Drupal の用語では、 で起動hook_user()しません$op = 'login')。

Shibboleth コードを見ると、その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());
      }
    }
    [...]

注:テストされていないコードです。タイプミスやその他のばかげた見落としに注意してください ;)

これを行う場合は、上記のリンク先のバグ レポートにパッチとして送信することをお勧めします。(明らかに動作する場合のみ;)

于 2010-10-20T20:48:19.927 に答える
0

Drupal は実行hooksされます。つまり、モジュールはコードの一部を実行する機会を得ます。たとえば、ログイン時に hook_user が呼び出されます。

多くの場合、モジュールはdrupal_goto()そのようなフック内で a を呼び出します。これは激しく壊れます。Drupal_goto はすべてを強制終了し、リダイレクト ヘッダーを送信してから、アプリケーションを終了します。他のフックは実行されません。

  1. フックは、drupal_goto()、die()、またはその他の破壊的な関数を呼び出してはなりません。しかし、人々がこの規則を破ることを妨げるものは何もないので、人々 (モジュール) はそれを破るでしょう。
  2. 同じ理由で、form_alter は決して goto や die などを呼び出すべきではありません。

devel モジュールをインストールし、「リダイレクトを表示」の設定を切り替えることで、「不正な」goto を見つけることができます。

于 2010-10-21T10:19:43.980 に答える
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」は、認証モジュールよりも大きい任意の数値です。

于 2010-10-20T11:21:45.047 に答える