Drupal与Web服务身份验证

时间:2011-12-15 13:50:07

标签: drupal authentication wsdl

我已经建立了一个简单的Drupal网站,即将完成 这个网站需要完全锁定,除了弹出框,允许你登录,这很好,但登录不应该通过Drupal的标准身份验证,而是需要将用户名和密码传递给Web服务对于登录成功或失败,返回true或false。

我可以构建弹出窗口,但是如何通过Web服务路由身份验证,并打开会话以停止直接链接而无需登录。我需要检查的是该人员是在父站点注册的(谁提供了Web服务)。

1 个答案:

答案 0 :(得分:3)

第1步是创建一个新模块。

我发现这个参考有用:http://yetanotherprogrammingblog.com/node/14

此解决方案基于drupal-6。 7中存在差异。

在模块中,您需要覆盖hook_login_validate。例如

function mymodule_login_validate($form, &$form_state) {
   $username = $form_state['values']['name'];

   // do if condition to see if your authentication is required.  
   // e.g. you might want to keep the drupal administration users.
   if (_mymodule_use_webservice_login($username)) {
     // We are logging in using service.
     if (_mymodule_validate_password($username, $form_state['values']['pass']) {
       user_external_login_register($username, 'mymodule');
       user_authenticate_finalize($form_state['values'];
    } // else drop through to the end and return nothing - Drupal will handle the rejection for us
   }
} else {
    // Username is not an member number, so use standard Drupal authentication function
    user_login_authenticate_validate($form, &$form_state);
}

在上面的注释中

  • 您必须在标题中使用_use_webservice_login创建该函数。测试是否转到REST服务。我喜欢将它们放入php类中以实现命名空间的健全性。
  • 您需要创建执行凭据测试的功能。 _mymodule_validate_password。这适用于您的服务。
  • 按照正常的drupal - 将'mymodule'更改为您创建的模块的名称,以便没有命名空间冲突。

我正在连接grails(spring / java)应用程序来调用该服务。这主要决定了make和变量的调用。我使用内置的grails身份验证服务进行身份验证并覆盖它以进行自定义身份验证。针对休息服务的电话应该是类似的。您需要一个http请求并解析响应。

我的PHP类执行_mymodule_validate_password的片段是:

$headers = array(
        'Content-Type' => 'application/x-www-form-urlencoded',
        'X-Requested-With' => 'XMLHttpRequest',
    );

    // _spring_security_remember_me
    $data = array(
        'j_username' => urlencode($username),
        'j_password' => urlencode($password),
        '_spring_security_remember_me' => 'on',
    );

    $query_string = http_build_query($data, '', '&');

    // WARNING - API changes in drupal 7
    // CAUTION - don't allow it to retry. Grails gives us a redirect which drupal_http_request follows, losing the cookie
    $response = drupal_http_request($endpoint_url, $headers, 'POST', $query_string, 0);

    // Did the initial login succeed.
    if ($response->code != 200 && $response->code != 302) {
        watchdog(self::module_name, self::module_name, 'Failed to log in %error.', array('%error' => $response->status_message));
        // FAIL
        return false;
    }

    // Initial login success. Follow the redirect. 
    // Redirected request. Look for 200 && {"success":true,"username":"888"}
    $redirect_response = drupal_http_request($response->redirect_url, array(), 'GET', NULL);

    // The true success criteria
    if ($redirect_response->code == 200 && array_key_exists('Set-Cookie', $response->headers)) {
        // Authentication worked.
        $response_data = json_decode($redirect_response->data);
        if (property_exists($response_data, 'success') && $response_data->success &&
                property_exists($response_data, 'username')) {
            $login_success = true;
        } else {
            return false;
        }

在一天结束时,我的请求给了我一个JSON {“成功”:true,“username”:“888”}。用户名是多余的。

如果对提供数据的服务进行身份验证,Grails会进行重定向。您可以检查从Web服务获得“200”并完成,或者只是检查您的JSON数据是否相当于“成功”。在上面的例子中,我们检查身份验证,记录重定向,然后调用重定向来获取身份验证数据。

您可以从服务返回基本的drupal配置文件信息并设置详细信息。覆盖mymodule_user以访问更新后回调。我更新每次登录的详细信息,因为后端是主要的数据来源。本文顶部的参考使用'update'。

function mymodule_user($type, &$edit, &$account, $category = null) {
   switch ($type) {


    case 'login' :
        // Login should theoretically fail if the details don't get set.
        ... whatever you have to do to get the details. I call my class.   
       user_save($account, array('mail' => $fedAuth->email_address));
    case 'logout' :
        // remove the grails cookies.

}

}

根据您尝试做的事情,这里的乐趣可能不会结束。在我的情况下,我必须更新自定义配置文件信息并保存客户端cookie以记录后续Web服务调用的登录详细信息。一些人认为这不是“安宁”,因为在网络服务提供商中有一个drupal会话和一个会话。