如何将一个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.");
}