Simple Machines Community Forum

Customizing SMF => SMF Coding Discussion => Topic started by: anonymous001 on April 13, 2019, 06:13:38 AM

Title: SMF 2.0.15 external authentication
Post by: anonymous001 on April 13, 2019, 06:13:38 AM
Dear users,

I'm using SMF version 2.0.15 at the moment for one of my projects.


Title: Re: SMF 2.0.15 external authentication
Post by: Arantor on April 13, 2019, 06:30:25 AM
SMF *can* be used for that, though it's really fiddly to do, and honestly I don't think we encourage it on the basis that SMF's session handling system is robust and proven after more than 15 years (including hardened against session fixation attacks, something most libraries don't actually do well)

In theory you can do it off the integrate_verify_member hook provided you return the user id of an account in SMF from the function you need to call.

The opposite, though, integrating into SMF is really easy where it's just including one file (SSI.php) and you're done for authentication, and it's fairly easy to register a new user in that situation (include Subs-Members.php, then call registerMember())
Title: Re: SMF 2.0.15 external authentication
Post by: anonymous001 on April 13, 2019, 06:36:52 AM
Dear Arantor,

thanks, where to find infos about integrate_verify_member()?
So I would use integrate_verify_member() to sign in a user?

SSI.php is used to register a new user (insert it into database).
Title: Re: SMF 2.0.15 external authentication
Post by: Arantor on April 13, 2019, 07:15:59 AM
No, integrate_verify_member is a hook; you set it to be a function in your application so that SMF will call it during authentication. Check the manual for Integration Hooks.

And no, SSI.php is used for external integrations, you include it and the SMF user is then loaded, it's also useful as a mini bootstrap outside of SMF for accessing SMF methods in external systems.

Though honestly, I get the horrible impression that this is going to be a long, painful journey for you because you haven't given any details of your app. For example, what password storage method are you using? More or less secure than SMF's?
Title: Re: SMF 2.0.15 external authentication
Post by: anonymous001 on April 13, 2019, 08:44:52 AM
I would like to "insert" the user into the SMF users table too.
I would generate a "random" password, it's never shown to the user, in the end I would disable all SMF based login routes.

-Registration is already done, since I included the register function into the SSI.php

function ssi_RegisterUser($options)
{
require_once($sourcedir . '/Subs-Members.php');
        //call the registerMember() with parameters...


}


Now I only would like to ask how I can login / logout a user by for example username or user_id into SMF application from my own code.
Title: Re: SMF 2.0.15 external authentication
Post by: Arantor on April 13, 2019, 08:47:56 AM
So, like I said, create a function inside your code, that can work out the current user however you do that (I have no idea since you don't seem to want to tell me anything about your app which makes it hard to help you), this function must return the user ID that would be inside SMF, then you put the name of the function in the settings table under the name 'integrate_verify_user' like the manual talks about under the integration hooks page.

I'm not being funny, but the amount of evasion about your app makes me concerned about its security and that you would be infinitely better bridging out from SMF rather than bridging into it.
Title: Re: SMF 2.0.15 external authentication
Post by: anonymous001 on April 13, 2019, 08:53:44 AM
Dear Arantor,

my application is a laravel framework based application, but this isn't that important atm.
-As I understand hooks in SMF, the whole code needs to be under the SMF dir, this will not be possible, since my own application is based under another webroot, so I'm a bit confused, how to use the hooks.

All I need at the moment is a way to login / logout a user by code and using his ID. The internal user_id is stored inside my users table of my application for sure.
Title: Re: SMF 2.0.15 external authentication
Post by: anonymous001 on April 14, 2019, 02:50:30 AM
Registration is now already done, I'm using the SMF database (so no edits to the system of SMF itself is needed) and my own application just stores the internal SMF member_id.

I've extended the SSI.php by this function:

// Custom function to login a user by the internal SMF user_id into the community
function ssi_LoginUserById($userId)
{

global $txt, $scripturl, $user_info, $user_settings, $smcFunc;
global $cookiename, $maintenance, $modSettings, $context, $sourcedir;
require_once($sourcedir . '/LogInOut.php');

// Load cookie authentication stuff.
require_once($sourcedir . '/Subs-Auth.php');

//load user details
$request = $smcFunc['db_query']('', '
SELECT passwd, id_member, id_group, lngfile, is_activated, email_address, additional_groups, member_name, password_salt, openid_uri,
passwd_flood
FROM {db_prefix}members
WHERE id_member = {string:userId}
LIMIT 1',
array(
'userId' => $userId,
)
);

$user_settings = $smcFunc['db_fetch_assoc']($request);

// Call login integration functions.
call_integration_hook('integrate_login', array($user_settings['member_name'], isset($_POST['hash_passwrd']) && strlen($_POST['hash_passwrd']) == 40 ? $_POST['hash_passwrd'] : null, $modSettings['cookieTime']));

// Get ready to set the cookie...
$username = $user_settings['member_name'];
$user_info['id'] = $user_settings['id_member'];

// Bam!  Cookie set.  A session too, just in case.
setLoginCookie(60 * $modSettings['cookieTime'], $user_settings['id_member'], sha1($user_settings['passwd'] . $user_settings['password_salt']));

// Reset the login threshold.
if (isset($_SESSION['failed_login']))
unset($_SESSION['failed_login']);

$user_info['is_guest'] = false;
$user_settings['additional_groups'] = explode(',', $user_settings['additional_groups']);
$user_info['is_admin'] = $user_settings['id_group'] == 1 || in_array(1, $user_settings['additional_groups']);

// Are you banned?
is_not_banned(true);

// An administrator, set up the login so they don't have to type it again.
if ($user_info['is_admin'] && isset($user_settings['openid_uri']) && empty($user_settings['openid_uri']))
{
$_SESSION['admin_time'] = time();
unset($_SESSION['just_registered']);
}

// Don't stick the language or theme after this point.
unset($_SESSION['language'], $_SESSION['id_theme']);

// First login?
$request = $smcFunc['db_query']('', '
SELECT last_login
FROM {db_prefix}members
WHERE id_member = {int:id_member}
AND last_login = 0',
array(
'id_member' => $user_info['id'],
)
);
if ($smcFunc['db_num_rows']($request) == 1)
$_SESSION['first_login'] = true;
else
unset($_SESSION['first_login']);
$smcFunc['db_free_result']($request);

// You've logged in, haven't you?
updateMemberData($user_info['id'], array('last_login' => time(), 'member_ip' => $user_info['ip'], 'member_ip2' => $_SERVER['BAN_CHECK_IP']));

// Get rid of the online entry for that old guest....
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_online
WHERE session = {string:session}',
array(
'session' => 'ip' . $user_info['ip'],
)
);
$_SESSION['log_time'] = 0;

// Just log you back out if it's in maintenance mode and you AREN'T an admin.
if (empty($maintenance) || allowedTo('admin_forum'))
redirectexit('action=login2;sa=check;member=' . $user_info['id'], $context['server']['needs_login_fix']);
else
redirectexit('action=logout;' . $context['session_var'] . '=' . $context['session_id'], $context['server']['needs_login_fix']);
}


Running the function is working, but I get redirect to the board and it says:

An Error Has Occurred!
You were unable to login. Please check your cookie settings.


It seems like there is some additional cookie check, I guess on some domain based security checks?
My appllication is running on: domain.com
My SMF installation on: smf.domain.com

SMF paths itself are all correct, no missing CSS, etc. any idea how to get the automatic login running?
Title: Re: SMF 2.0.15 external authentication
Post by: Kindred on April 14, 2019, 09:30:58 AM
Turn on subdomain independent cookies