Firefox PHP

Login from outside forum (Own authentication system and login page)

Posted by graab 
Re: Login from outside forum (Own authentication system and login page)
December 20, 2007 06:08PM
Thanks for the feedback. Especially since all the user API stuff is quite new for Phorum. It's good to hear about success stories for boosting our confidence in this new code ;-)


Maurice Makaay
Phorum Development Team
my blog linkedin profile secret sauce
Re: Login from outside forum (Own authentication system and login page)
March 18, 2008 01:57AM
I read this thread because i also wanted to integrate phorum with my website.
I've opted for the first approach though, because that means i won't have to touch the phorum-code itself.
I did try te restore_session_hook solution to see if that worked, but got kinda stuck. The documentation says:

Quote

Call time:

Just before Phorum runs its own session restore code in the user API function phorum_api_user_session_restore().

Since it wanted that $sessions variable i modified the in this way:

    $check_session = array(
        PHORUM_SESSION_LONG_TERM  => 0,
        PHORUM_SESSION_SHORT_TERM => 0,
        PHORUM_SESSION_ADMIN      => 0
    );
// this is the line i added:
$check_session = phorum_mod_foo_user_session_restore($check_session);

That didn't work however. So maybe the sample can include the precise position of where to call the function and what to do with the return value?

Anyways, as i said i've opted for the first approach, so i can upgrade forum whenever i like without having to rewrite the api/user.php after i've done so. There were two lines missing in the original attempt earlier in this thread:

function logingPhorumUser($userId)
{
	$dir = realpath(/*path to forum dir */);
	chdir( $dir );

	define("PHORUM", 1);
	global $PHORUM;

	include_once("./include/db/config.php");
	include_once("./include/db/mysql.php");
	include_once("./include/api/base.php");
	include_once("./include/api/user.php");
	// this one was missing
	include_once("./include/constants.php");

	// and this one was missing
	phorum_db_load_settings();

	// this one is not necessary anymore
//	$PHORUM['use_cookies'] = PHORUM_USE_COOKIES;

	phorum_api_user_set_active_user(PHORUM_FORUM_SESSION, $userId);
	phorum_api_user_session_create(PHORUM_FORUM_SESSION, PHORUM_SESSID_RESET_LOGIN);

//	print_r( $PHORUM );
}

Like this, it works perfectly (for me at least)
Of course you have to make sure - as pointed out before - that you also have to make sure a phorum-user is created in the phorum-user-table of your database. Unfortunately, the database i have available doesn't support triggers and stored procedures yet, but if it does in your case, that would seem like the way to go for me.

Thought i'd post that here in case anyone else wants to do the same
Re: Login from outside forum (Own authentication system and login page)
March 18, 2008 04:05AM
Quote

That didn't work however. So maybe the sample can include the precise position of where to call the function and what to do with the return value?

It is not required to change the code to call your function. That is what we invented the module system for. That function that I posted as an example is supposed to be a hook function that is part of a module. The module info.txt for the module would contain a line like:
hook: user_session_restore|your_mod_function_for_user_session_restore
The function your_mod_function_for_user_session_restore() would be stored in a module script like mods/your_mod/your_mod.php.

For more information, see the documentation on this site.

DOCS -> Developer Manual -> Modules
DOCS -> Developer Manual -> Module Hooks -> User authentication and session handling


Maurice Makaay
Phorum Development Team
my blog linkedin profile secret sauce
Re: Login from outside forum (Own authentication system and login page)
April 03, 2008 12:45AM
Hi,

I'm using Phorum version 5.2.7 and I used this "user_session_restore" hook solution... it worked like a charm. I keep my own user table sync'd with the phorum table and it all works. Thank you so much!

Now, the only problem I have is, how do I do the same thing for the admin part of the phorum? If I try to access "admin.php", I'm still asked for the username and password even though I logged in using my own authentication system.

I currently have an admin account I created manually so I can do the phorum maintenance while I'm developing, but I'll have to have my own application handle the creation of admins when I'm done. I have it all set up so my own application handles the promoting/demoting from users to admin and keeps it all sync'd in the tables (I checked it using that manually created admin account). But when I log in my app with an admin account, it still doesn't automatically log me in into Phorum's admin.php.

That wouldn't be much of a problem if I could actually log in using the admin.php form, but I can't because the phorum user table doesn't have passwords in them, since in theory when using external authentication, the phorum user table doesn't need them. I read somewhere else to just put an impossible password like *NO PASSWORD SET* in there, so when I create the phorum users to sync with my own system's users, that's what goes in the password fields.

Is there another hook I have to hook my module to so I can bypass the admin login too? I looked in the docs but didn't see anything. Or am I missing something in my implementation?

My module's code is this:

<?php

/* phorum module info
hook:  user_session_restore|external_authentication
title: External Authentication
desc:  This module uses a external authentication system to log user into Phorum.
*/


function external_authentication($sessions)
{
    // Override the session handling for front end forum sessions.
    // Retrieve a session from a standard PHP session by first
	// starting a PHP session if that was not done yet...
    if (!session_id()) session_start();

    // ...and then retrieving the user_id of the current user
    // from the PHP session data. The user_id is really the
    // only thing that needs to be remembered for a Phorum
    // session, because all other data for the user is stored
    // in the database. If no user id was set in the session,
    // then use FALSE to flag this to Phorum.
    $phorum_user_id = empty($_SESSION['myuserid'])
                    ? FALSE : $_SESSION['myuserid'];

    // If we only use session inheritance for the front end
    // forum session (highly recommended for security), then
    // We keep PHORUM_SESSION_ADMIN at NULL (default value).
    // The other two need to be updated. If the main system does
    // not use the concept of one long and one short term cookie
    // (named "tight security" by Phorum), then simply assign
    // the user_id to both PHORUM_SESSION_LONG_TERM and
    // PHORUM_SESSION_SHORT_TERM.
    $sessions[PHORUM_SESSION_SHORT_TERM] = $phorum_user_id;
    $sessions[PHORUM_SESSION_LONG_TERM] = $phorum_user_id;

    return $sessions;

}

?>

Thanks again,

-- Mauro



Edited 4 time(s). Last edit at 04/03/2008 10:50AM by voivoed.
Re: Login from outside forum (Own authentication system and login page)
April 03, 2008 04:14AM
The copied comments in your module code already give you the answer ;-)
    // If we only use session inheritance for the front end
    // forum session (highly recommended for security), then
    // We keep PHORUM_SESSION_ADMIN at NULL (default value).
What should work is adding code to your module that sets the authenticated user_id for the admin session. So you first check if the user that is logged into your system is administrator and if yes, you assign this:
    $sessions[PHORUM_SESSION_ADMIN] = $phorum_user_id;

What I do myself, is fill the Phorum user table with passwords for admin users from my main system. Therefore, those users are known by Phorum too for authentication and I can login in the admin interface using these. This cleanly separates the authentication sessions, which I prefer for security. It prevents session riding, since front-end code cannot trick you into running admin code, as long as you are only logged in for the front-end.

What method you like best is of course up to you.


Maurice Makaay
Phorum Development Team
my blog linkedin profile secret sauce
Re: Login from outside forum (Own authentication system and login page)
April 03, 2008 11:02AM
Hahahahahaha I'm so dumb, it was right in front of me... sorry about that.

Anyway, I ended up modifying the module instead of keeping track of passwords, but I added some extra code in there:

1) I'm checking to see if the module is invoked within Phorum;
2) I had to destroy any admin sessions beforehand, otherwise they would linger on until I closed the browser, even after I had logged out of admin thru my authentication system;
3) also, I'm setting the admin user based on the permission for that user in the phorum user table (which is kept in sync with my own user table), because I don't have that information in the session object.

I hope I did ok. I don't know how bad this solution is, security-wise. Anybody has any idea? How easy is it to fool this module?

Thanks again.

<?php

/* phorum module info
hook:  user_session_restore|external_authentication
title: External Authentication
desc:  This module uses a external authentication system to log user into Phorum.
*/

// Check if we are loaded from the Phorum code.
// Direct access to this file is not allowed.
if (! defined("PHORUM")) return;


function external_authentication($sessions)
{
	// Override the session handling for front end forum sessions.
	// Retrieve a session from a standard PHP session by first
	// starting a PHP session if that was not done yet...
	if (!session_id()) session_start();

	// ...and then retrieving the user_id of the current user
	// from the PHP session data. The user_id is really the
	// only thing that needs to be remembered for a Phorum
	// session, because all other data for the user is stored
	// in the database. If no user id was set in the session,
	// then use FALSE to flag this to Phorum.
	$phorum_user_id = empty($_SESSION['myuserid'])
                    ? FALSE : $_SESSION['myuserid'];
	
	// Destroy any current admin session, to prevent
	// someone riding on a previous admin session in
	// browser (if browser wasn't closed afterwards)
	phorum_api_user_session_destroy(PHORUM_ADMIN_SESSION);
	
	// The other two need to be updated. If the main system does
	// not use the concept of one long and one short term cookie
	// (named "tight security" by Phorum), then simply assign
	// the user_id to both PHORUM_SESSION_LONG_TERM and
	// PHORUM_SESSION_SHORT_TERM.
	$sessions[PHORUM_SESSION_SHORT_TERM] = $phorum_user_id;
	$sessions[PHORUM_SESSION_LONG_TERM] = $phorum_user_id;
	$sessions[PHORUM_SESSION_ADMIN] = NULL; // defaults to non-admin

	// If user is admin, fill out the following. This changes
	// the default behaviour for external logins from the
	// recommended behavior.
	if ($phorum_user_id) {
		// check admin flag
		$user_data = phorum_api_user_get($phorum_user_id, TRUE);
		if ($user_data && ($user_data['admin'] > 0)) {
			// user is admin
			$sessions[PHORUM_SESSION_ADMIN] = $phorum_user_id;
		} 
	}

    return $sessions;

}

?>
Re: Login from outside forum (Own authentication system and login page)
April 03, 2008 11:18AM
You have to destroy the admin session explicitly here, because you are using NULL for the admin flag. You can handle this more gracefully though. From the hook docs:
       What the module has to do, is fill the values for each of these
       keys with the user_id of the Phorum user for which the session that
       the key represents should be considered active. Other options
       are FALSE to indicate that no session is active and NULL to
       tell Phorum to handle session restore on its own.
With NULL assigned, Phorum will still run its own session restoring code. That is why the admin session stays active after logging out. However, if you set the field to FALSE, then you tell Phorum explicitly that no session must be restored and the admin pages will follow the user authentication status nicely.

One other comment that I have, is that the phorum_api_user_get() call doesn't need the TRUE argument. That one will make the function return group data as well. But that isn't needed here. If you use FALSE there, you will still be able to check the admin field in the return data.

For the rest, this seems like a good solution to me. Well done ;-)


Maurice Makaay
Phorum Development Team
my blog linkedin profile secret sauce
Re: Login from outside forum (Own authentication system and login page)
April 03, 2008 11:32AM
Do you really want to make some of your users admins? It isn't that hard to really muck up a forum if they don't know what they are doing and admins have full access to all of the forums.
Re: Login from outside forum (Own authentication system and login page)
April 03, 2008 11:36AM
Thanks again, Maurice. I made the changes you suggested, everything is working perfectly now.

I'm posting my final implementation here as a reference for other people, if anyone wants to do something similar. This is what I did to get all this working:

1) Added some code to my external authentication system to create user entries in the phorum's user table, and to keep them in sync (i.e. if e-mail changes, change it in the phorum table too, if my user is no longer an admin, change status in the phorum table too, and so on).

2) I don't store passwords in the phorum's user table though, they're set to something like "*NO PASSWORD SET*", and what that means is that you cannot use phorum's own login/logout pages any more. I removed those from my templates so the users don't even see the links to them.

3) I created an phorum module (see code below), uploaded it in the mods folder, then activated it through phorum's admin area.

That's it. Now users log in and out using my application, and they have a link to my installation of phorum.

I hope this helps.

<?php

/* phorum module info
hook:  user_session_restore|external_authentication
title: External Authentication
desc:  This module uses a external authentication system to log user into Phorum.
*/

// Check if we are loaded from the Phorum code.
// Direct access to this file is not allowed.
if (! defined("PHORUM")) return;


function external_authentication($sessions)
{
    // Override the session handling for front end forum sessions.
    // Retrieve a session from a standard PHP session by first
	// starting a PHP session if that was not done yet...
    if (!session_id()) session_start();

    // ...and then retrieving the user_id of the current user
    // from the PHP session data. The user_id is really the
    // only thing that needs to be remembered for a Phorum
    // session, because all other data for the user is stored
    // in the database. If no user id was set in the session,
    // then use FALSE to flag this to Phorum.
    $phorum_user_id = empty($_SESSION['userfid'])
                    ? FALSE : $_SESSION['userfid'];
	
    // The other two need to be updated. If the main system does
    // not use the concept of one long and one short term cookie
    // (named "tight security" by Phorum), then simply assign
    // the user_id to both PHORUM_SESSION_LONG_TERM and
    // PHORUM_SESSION_SHORT_TERM.
    $sessions[PHORUM_SESSION_SHORT_TERM] = $phorum_user_id;
    $sessions[PHORUM_SESSION_LONG_TERM] = $phorum_user_id;
	$sessions[PHORUM_SESSION_ADMIN] = FALSE; // ignores any previous admin sessions

	// If user is admin, fill out the following. This changes
	// the default behaviour for external logins.
	if ($phorum_user_id) {
		// check admin flag
		$user_data = phorum_api_user_get($phorum_user_id);
		if ($user_data && ($user_data['admin'] > 0)) {
			// user is admin
			$sessions[PHORUM_SESSION_ADMIN] = $phorum_user_id;
		} 
	}

    return $sessions;

}

?>



Edited 1 time(s). Last edit at 04/03/2008 06:43PM by voivoed.
Re: Login from outside forum (Own authentication system and login page)
April 03, 2008 11:42AM
DavidVB, I'm aware of that, the thing is that the administration of the site will pass from hand to hand from time to time, so I had to add the ability for the old admin to promote the new admin from "user" to "admin" and then demote him/herself to a regular user. At least that's the idea...
Sorry, only registered users may post in this forum.

Click here to login