更新
@Elin:
感谢您的链接!对于糟糕的评论表示抱歉,我只是不打算使用换行符
但我尝试的并不是真正改变用户。我只是想创造它。
但是,我改变了我的插件应该做的计划。也许你知道如何使我的计划有效:
我探讨了以下内容:
如果我在Joomla DB中有一个用户名1,密码为1的用户和另一个密码的同一用户(这很重要,因为否则用户会直接在我的外部数据库中对Joomla DB进行身份验证),请使用密码登录前端外部DB工作没有任何问题。
登录后端只能使用Joomlas DB中的用户密码(以及其他人),即使所有细节都相同(即使是组)。
如何将针对外部数据库进行身份验证的用户登录到后端?!
还有一次非常感谢!
_____ 更新结束 ____
我有一个(希望)小问题让我发疯:
我juste为Joomla 3.1写了一个插件。此插件允许针对外部Web服务器脚本进行身份验证(使用onUserAuthenticate())。工作正常。
比我认为最好使后端访问成为可能。所以我写了第二个插件来实现这一点。 此插件搜索Joomlas DB中的授权用户,如果找不到 #__ users 和 #__ user_usergroup_map ,则将其添加。到这里它也可以正常工作。
现在我的问题:
前端登录有效,后端没有(仅显示空白页)。 我是否还必须将用户插入任何其他表格?或者是否有任何遗漏?我忘记了什么吗?!
我的登录插件代码:
<?php
/**
* @package Joomla.Plugin
* @subpackage Authentication.External
*
* @copyright Copyright (C) 2014 Stefan Herzog. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* External Authentication Plugin
*
* @package Joomla.Plugin
* @subpackage Authentication.external
* @since 3.1
*/
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
class PlgUserExternal extends JPlugin
{
/**
* Load the language file on instantiation. Note this is only available in Joomla 3.1 and higher.
* If you want to support 3.0 series you must override the constructor
*
* @var boolean
* @since 3.1
*/
protected $autoloadLanguage = true;
/**
* This method should handle any authentication and report back to the subject
*
* @param array $credentials Array holding the user credentials
* @param array $options Array of extra options
* @param object &$response Authentication response object
* @param object $response Authentication response object
* @param array $result Authenticataion response array
* @return boolean
*
* @since 1.5
*/
public function onUserLogin($user, $options = array())
{
// Set default values
$allow_backend_access = FALSE;
if(isset($user['admin']) AND $user['admin'] === 1)
{
$allow_backend_access = TRUE; // works! This parameter is delievered with $response from onUserAuthentication()
}
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select all records from the user profile table where key begins with "custom.".
// Order it by the ordering field.
$query->select($db->quoteName(array('id')));
$query->from($db->quoteName('#__users'));
$query->where($db->quoteName('username') . ' = '. $db->quote($user['username']));
// Reset the query using our newly populated query object.
$db->setQuery($query);
// Load the results as a list of stdClass objects (see later for more options on retrieving data).
$results = $db->loadAssoc();
if(count($results) == 0)
{
$checkUser = 0;
}
elseif(count($results) >= 1)
{
$checkUser = 1;
$user_id = $results['id'];
}
if($checkUser === 0)
{
// Create a new query object.
$query = $db->getQuery(true);
// Insert columns.
$columns = array('name', 'username','email','password');
// Insert values.
$values = array($db->quote($user['fullname']), $db->quote($user['username']), $db->quote($user['email']), $db->quote($user['password']));
// Prepare the insert query.
$query
->insert($db->quoteName('#__users'))
->columns($db->quoteName($columns))
->values(implode(',', $values));
// Set the query using our newly populated query object and execute it.
$db->setQuery($query);
$db->query();
$user_id = $db->insertid();
if($user_id >> 0)
{
/************* Insert user into user_usergroup_map table *************/
foreach($user['groups'] AS $group_id)
{
$columns = NULL;
$values = NULL;
$query = $db->getQuery(true);
// Insert columns.
$columns = array('user_id', 'group_id');
// Insert values.
$values = array($db->quote($user_id), $db->quote($group_id));
// Prepare the insert query.
$query
->insert($db->quoteName('#__user_usergroup_map'))
->columns($db->quoteName($columns))
->values(implode(',', $values));
// Set the query using our newly populated query object and execute it.
$db->setQuery($query);
$db->query();
}
//$instance = $this->_getUser($user, $options);
}
}
// $instance = JFactory::getUser($user_id); // works
}
}?>
感谢您的帮助!
祝你好运 斯蒂芬
答案 0 :(得分:0)
这些非常复杂,哈哈。提出一些指导的几点想法。
首先,您应该只需要一个身份验证插件来处理前端和后端身份验证。在身份验证插件中,您可以使用以下命令识别请求是来自前端还是后端登录表单:
JFactory::getApplication()->isSite();
和
JFactory::getApplication()->isAdmin();
其次,我不确定你是否从你的帖子中做到这一点,但是当新的站点访问者对你的外部数据库进行身份验证时,无论他们是否在前面进行身份验证,你都应该始终在数据库中创建一个Joomla用户或后端。
第三,在创建用户时,我建议让Joomla核心通过使用JUser对象创建新用户来完成所有工作。例如,您可以创建并保存用户:
$user = new JUser();
$user->set('name', $columns['name']);
$user->set('username', $columns['username']);
$user->set('email', $columns['email']);
$user->set('password', $columns['password']);
$user->save();
现在这当然非常简化,没有任何数据验证或清理,因此您必须努力在代码中执行这些检查。
编辑1
正如op指出的那样,我没有提供有关这些团体的任何反馈。如果您知道组ID,则可以使用用户帮助程序类添加它。执行save:
后,您应该在JUser对象中拥有新的用户IDJUserHelper::addUserToGroup($user->id, $group_id);
祝你好运!
答案 1 :(得分:0)
Joomla后端具有一定的内置安全功能,这使得登录后端基本上更加困难。例如,如果您曾尝试针对后端发出REST请求,则会出现白屏。如果你在后端查看com_login,你会发现它与com_users的登录视图完全不同。您需要基本上强制使用创建过程(可能对用户不可见)来完成前端。要允许管理员访问您要执行的操作,请创建具有login.admin权限的默认用户组。您可以在插件中覆盖该配置设置。
如上所述,您应该只使用Joomla API来创建用户,因为它很复杂,涉及许多表,您需要正确处理加密。您可能需要用户插件以及身份验证插件。您可能想要了解Cookie身份验证在Joomla中的工作方式,尽管它在后端被特别阻止。
更新
我不明白您是在尝试更改现有用户。如果查看JUser代码,您将看到更改用户需要与具有更改用户权限的用户进行会话。您拥有的会话是一个用户的会话(因为她的组尚未更改)肯定没有用户编辑权限。进一步添加会话需要属于超级管理员的超级管理员。问题是你没有会话。有一种方法可以假装我使用here。由于您实际上知道管理员用户的ID,因此您甚至可以对其进行硬编码。
更新2
由于我提到的(与REST相同的问题),您将不得不面临挑战。基本上,两个应用程序中的授权和认证流程是不同的。在后端你必须通过登录,所以你的插件真的需要模拟登录过程。请注意它在JApplicationAdmin中是如何硬编码的。有一些插件可以为管理员实现基本身份验证,这是另一种可能性,但只有当你在我看来使用ssl时,除非你在100%的防火墙后面。 Com_config执行一个可能有用的共享会话。