Hi Friends,
I'm using two drupal 6 websites and want to use external authentication in my website.
As you know in Druapl 6, There isn't drupal.module . How can we enable external authentication capability?
Where is the function related to XML-RPC External Authentication?
Could you please describe more. I searched the website and couldn't find a good issue about drupal 6. All of them was about drupal 5 and 4.

Thanks in advance!

Comments

rowshan’s picture

Indeed i want to hack the concerned functions to this issue especailly functions of XML RPC and craete a XML-RPC server to response the requests of XML-RPC client.

rowshan’s picture

Please help me just with one sentence.
I couldn't find any issue about drupal 6.x, All issues about 5.x
Where is the drupal.module in drupal 6.x ?

almaceria’s picture

Hi rowshan.
I was looking for the same feature but unfortunately the drupal.module, the hook_auth and the hook_info were gone when all moved to drupal 6. (see http://drupal.org/node/114774#dist-auth)
Reason was to allow different and more flexible authentication methods, like openid (http://drupal.org/node/148419)

So, from now on thing changes in a harder but more flexible way. I'm trying to figure out how to implement this into my module but for now this is what I've got:

1) You must implement the hook_form_alter to catch the login submit operation (use the $form_state and $form_id values to determine that) and include a callback to your module authentication function via the form validation handler:

function mymodule_form_alter (&$form, $form_state, $form_id) {
     if ($form_id == 'user_login' || $form_id == 'user_login_block' ) {
        if (isset($form_state['post']['name'])) {
             $form['#validate'][] = mymodule_login_validate();
        }
     }
}

2) In this way, you can call your module authentication function during the form validation process:

function mymodule_login_validate ($form, $form_state) {
    if (!mymodule_authenticate($form_state['values'])) {
        form_set_error('error','Sorry. Unrecognized username or password');
    }
}

3) The authentication function should launch 3 actions:
a) To determine if authentication succeds
b) To run user_external_login_register() function to get the user logged in or registered as an external-authenticated user
c) To run user_authenticate_finalize() function to write watchdog entries, session stamps and invoke user hooks with $op=login

So, is in the step 3.a. where you must put your call to the XML-RPC authentication.
In the other hand, if your sites are both installed in the same drupal instance (diferent sites under the "sites/" directory), you can take advantage of drupal features:
1) use the db_set_active() function to swap the local site database to the external site database
2) run a query in the "user" table to authenticate the user according to the data provided in the login form
3) turn back the active database to your local site database, using again the db_set_active() function

If you want to use the xml-rpc authentication I think you should have a glance at the xmlrpc() function in the API documentation site.

You may want to take a look on a running example for external authentication in the openid.module, distributed in the drupal core package.

Hope it helps.

sushilmasti’s picture

Thanks to the previous entry - I used this code to authenticate using a web service. aoladmin is the name of my module.

function aoladmin_form_alter (&$form, $form_state, $form_id) {
     if ($form_id == 'user_login' || $form_id == 'user_login_block' ) {
        if (isset($form_state['post']['name'])) {
             $form['#validate'][] = aoladmin_login_validate($form, $form_state);
        }
     }
}

function aoladmin_login_validate ($form, $form_state) {
	$auth_rtn = aoladmin_authenticate($form_state['post']);
    if (!$auth_rtn) {
    	  form_set_error('name', 
    	  t('Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>', 
    	  array('@password' => url('user/password'))));
    	
    }
}

function aoladmin_authenticate($form_values) {
	$username = $form_values['name'];
	$pass =  trim($form_values['pass']);
	
//	//only will authenticate email addresses through this
	if($username && $pass && strpos( $username, "@") != FALSE)
	{
		try
		{
			$client = new SoapClient("YOUR WSDL URL HERE",array('trace' => true));
			$parameters   = array('userName' => $username,
								  'password' => $pass
									);
			$response = $client->CALL-YOUR-WEB-SERVICE($parameters);
		} catch (Exception $e)
		{
			$response->message = $e->getMessage();
		}	
//		
	  	if(CHECK_FOR_SUCCESSFUL_LOGIN_HERE)
	  	{
                        //check if there is a user with the entered email address
	  		db_set_active('default');
	  		$sql_in = "select name from {users} where mail = '%s'";
	  		$name = db_result(db_query($sql_in, $username));
	  		if($name)
	  		{
	  			user_external_login_register($name, 'aoladmin');
	  			$edit = array();
                                //Interesting I was using user_authenticate_finalize(array()) - works fine through the web
                               //but when I wanted to bootstrap drupal for a script - the bootstrap process crashed at loading 
                               //my module
	  			user_authenticate_finalize($edit);
	  			return TRUE;
	  		}
	  		else
	  		{
	  			
	  			return FALSE;
	  		}
	  	}
	  	else
	  	{
			return FALSE;
	  	}

	}
	else
	{
		return FALSE;
	}
}
dreipunktnull’s picture

Hi,

I managed to login users coming from an external database but would like to reproduce the old behaviour of hook_auth() where the authentication process was finished when any of the registered functions returned TRUE. Now using the provided code in this thread I receive a form error and the login form is rendered again although the user is correctly logged in regardless of the table (local or external). How can I stop the authentication process if a valid user has been found and logged in in either the external or the local database? I guess a good starting point would be $form['#validate']...

Thanks in advance for your thoughts.

Best regards,
Björn

Edit: Solved like this:

function mymod_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_login' || $form_id == 'user_login_block') {
    $form['#validate'] = array('mymod_login_validate');
  }
}

function mymod_login_validate($form, &$form_state) {
  if (!empty($form_state['values']['name']) && !empty($form_state['values']['pass'])) {
  	db_set_active('otherdb');
  	$password = '';
  	if ($result = db_query("SELECT password FROM {table} WHERE username LIKE '%s'", $form_state['values']['name'])) {
        $password = db_result($result);
    }
    db_set_active('default');
    if ($password == '' || $password != $form_state['values']['pass']) {
      return user_login_authenticate_validate($form, &$form_state);
    }
    else {
      user_external_login_register($form_state['values']['name'], 'mymod');
      user_authenticate_finalize($form_state['values']);
      return TRUE;
    }
  }
}
toxiclung’s picture

hi,

i would also like to authenticate user from a mysql table with user & password columns.
how do i apply this code?

please help :D
thanks

ebeyrent’s picture

In D7, there is no user_authenticate_finalize(), use user_login_finalize() instead.