如何将一个Joomla网站ASP。网络页面。用户必须登录Joomla,但是一些页面与.net站点建成的。网络页面有自己的SQL Server数据库,其中Joomla使用MySQL数据库。
有趣的部分是如何。网页可以验证是否一个Joomla用户登录。重要的是,这是一种方法,但它不是最安全的方式。它是容易被破解,因为我使用一个cookie存储的(加密)Joomla用户ID,所以,如果你知道哪种饼干你需要而且能够解密和/或具有相同的密钥进行加密,你就可以伪造一个登录用户。请注意,这是一个可接受的风险。一个突破的影响将是小的。
如上所述,我使用一个cookie存储的Joomla用户ID必须加密提供尽可能多的安全。与下一个Joomla插件代码cookie登录事件创建。在注销事件cookie被删除。这个插件是Joomla 1.5写的,所以在更新的版本,所以在新版本可能需要一些改变.
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
require_once('TripleDES.php');
// Import library dependencies
jimport('joomla.plugin.plugin');
class plgUserSystemIntegration extends JPlugin
{
function plgUserOVSystemIntegration( &$subject, $config )
{
parent::__construct( $subject, $config );
}
function onLoginUser( $credentials, $options )
{
$user = &JFactory::getUser();
// Joomla session parameters
$userId = $user->get('id');
// Encrypt the userId to store in cookie
$key = $this->params->get('key'); // these keys are both used in PHP and .Net
$iv = $this->params->get('iv');
$crypt = new Crypt_TripleDES();
$crypt->setKey($key);
$crypt->setIV($iv);
$value = $crypt->encrypt(strval($userId));
// Encode string as text
$value = bin2hex($value);
setcookie("SIJ10", $value); // The cookie name is the identifier. It might be best to make this configurable
return true;
}
function onLogoutUser( $credentials, $options )
{
// Overwrite cookie
setcookie("SIJ10", "", time()-3600);
return true;
}
}
除了注销事件,需要做一些会话管理,以防用户没有注销。与下一个插件删除cookie Joomla会话已经结束。
deleted if the Joomla session has ended.
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
// Import library dependencies
jimport('joomla.plugin.plugin');
class plgSystemSystemIntegrationLogout extends JPlugin
{
function plgSystemOVSystemIntegrationLogout( &$subject, $config )
{
parent::__construct( $subject, $config );
}
function onAfterDispatch()
{
$user = &JFactory::getUser();
// If no user is logged in
if (!$user->get('id'))
{
// If cookie value was set
if(isset($_COOKIE["SIJ10"]))
{
// Overwrite cookie
setcookie("SIJ10", "", time()-3600);
}
}
}
}
现在的。网的部分。下一个方法(s)检索cookie和解密。hex2bin相当于PHP函数,二进制数据不能放在一个cookie。文本是解密en解析后一个整数。的基本假设是,只要是有可能的,一个用户登录。更重要的是,在SQL Server数据库中一个表包含一个应用级的用户(用于后端服务)的'知道'的Joomla ID,这样用户可以对数据库进行验证,这将使它更安全。
private void Authenticate()
{
string CookieUserId = "SIJ10";
if (Request.Cookies[CookieUserId] != null)
{
try
{
// Decode from hex
byte[] encodedDataAsBytes = hex2bin(Request.Cookies[CookieUserId].Value); // Change the text to the binary values
// Decrypt
TripleDES decryptor = TripleDES.Create();
UTF8Encoding encoding = new UTF8Encoding();
decryptor.Key = encoding.GetBytes("abcdefgajdhshsgshsjss12"); // It is best to make these keys configurable!
decryptor.IV = encoding.GetBytes("abcdefgh");
ICryptoTransform decrypt = decryptor.CreateDecryptor();
byte[] result = decrypt.TransformFinalBlock(encodedDataAsBytes, 0, encodedDataAsBytes.Length); // Decrypt
string returnValue = encoding.GetString(result);
int id = 0;
if (int.TryParse(returnValue, out id))
this.UserId = id;
else
{
// Redirect to the login page
Response.Redirect("~/Login");
}
// Some session management is needed
// Check for session timeout
if (Session["SessionTimeout"] == null)
{
// This is the first page request
Session["SessionTimeout"] = DateTime.Now;
}
else
{
// This needs to be included in every page (or use a baseclass) or
// called with every request
DateTime lastRequest = (DateTime) Session["SessionTimeout"];
if (DateTime.Now.Subtract(lastRequest).Minutes > 20)
{
Response.Redirect("~/Login");
}
else
{
// Update the timeout value
Session["SessionTimeout"] = DateTime.Now;
}
}
}
catch (Exception e)
{
Response.Redirect("~/Login");
}
}
else
Response.Redirect("~/Login");
}
private byte[] hex2bin(string hexdata)
{
if (hexdata == null)
throw new ArgumentNullException("hexdata");
if (hexdata.Length % 2 != 0)
throw new ArgumentException("hexdata should have even length");
byte[] bytes = new byte[hexdata.Length / 2];
for (int i = 0; i < hexdata.Length; i += 2)
bytes[i / 2] = (byte)(HexValue(hexdata[i]) * 0x10
+ HexValue(hexdata[i + 1]));
return bytes;
}
private int HexValue(char c)
{
int ch = (int)c;
if (ch >= (int)'0' && ch <= (int)'9')
return ch - (int)'0';
if (ch >= (int)'a' && ch <= (int)'f')
return ch - (int)'a' + 10;
if (ch >= (int)'A' && ch <= (int)'F')
return ch - (int)'A' + 10;
throw new ArgumentException("Not a hexadecimal digit.");
}