I had a similar use case in the past and i am giving some snippet, hope will help you. The key was user_login_finalize and then redirecting internally to the same page.
Load the user if already present or create and then load him
$user = user_load_by_name_and_password($username, $password); if ($user == FALSE) { $newuser = array( 'name' => $username, 'pass' => $password, // some password 'mail' => $email, // some email 'status' => 1, 'init' => $email, // some email id 'roles' => $roles, // some roles ); // New user is saved and loaded $user = user_save(drupal_anonymous_user(), $newuser); } user_login_finalize(); drupal_goto(get_current_url_with_query_params());
http://api.drupal.org/api/drupal/modules!user!user.module/function/user_login_finalize/7 Finalize the login process. Must be called when logging in a user
drupal_goto must be called as user_login_finalize() bootstraps the currently logged in user too late and hence will throw 'access denied' even for the page for which the user has permission. drupal_goto() makes sure that the user is properly bootstrapped and then is made to access the page again.
It is equivalent to reloading the page after the user has logged in but this is the only way i got my external login work. Refer User login using a token or ID (no password)