xavier gouley

› eZpublish SSO login Handler - Apache Kerberos module bypass

This week I had to make an eZpublish web site with an SSO authentication under eZpublish (NTLM). An SSO login handler is required. This login handler is executed by PHP and so is preceded by Apache authentication, with Kerberos Apache module.

The first problem comes when you want to let Kerberos authenticate the user (to give user data to PHP) or bypass authentication module if Kerberos cannot identify the user, to let eZpublish authenticate the user itself, with a classical form or another login handler : this parameter is not possible under Apache Auth modules, with a classical configuration like this:

<Directory /var/www/ezpublish>
    AuthType Kerberos
    KrbAuthRealms WASCOU.ORG
    KrbServiceName HTTP
    Krb5Keytab /root/wascou.keytab
    KrbMethodNegotiate on
    KrbMethodK5Passwd off
    Require valid-user
    Options All
</Directory>

The "Require valid-user" line will disallow site access until the user is not authenticated under Apache Kerberos module. This is the problem for users that need to be logged in with the classical form on eZpublish. Unfortunately there is no instruction to tell Kerberos to let a bypass in failure case (like with Basic or Digest modules, the same): Apache will give a HTTP 401 error, which is quite logical.

I suppose you know that eZpublish can call the user/login module from any URL that brings to a protected content: according to the user rights, a login form could be shown, and before this, a SSO login can be called. So there no way to indicate clearly to apache when eZpublish needs to login the user (to activate Kerberos authentication): telling "/user/login" URL is the only login URL is a mistake.

So, the solution is to play with well built Apache and PHP redirections, that the user cannot see, to call Kerberos module only when eZpublish needs it. Firstly, we will replace the above configuration with the following one, contained in a Location section, much more appropriated in our case :

<Location /ntlm/auth>
    AuthType Kerberos
    KrbAuthRealms WASCOU.ORG
    KrbServiceName HTTP
    Krb5Keytab /root/wascou.keytab
    KrbMethodNegotiate on
    KrbMethodK5Passwd off
    Require valid-user
    Options All
    ErrorDocument 401 /user/login
</Location>

Notice that the "/ntlm/auth" URL could bring us to an eZpublish module: this module must exist (you have to create it), but the PHP script behind this will never been executed and could remain empty (Apache and eZpublish will make redirections before this execution, see next step). Also notice the "ErrorDocument 401 /user/login" line, that will redirect the user if Kerberos cannot authenticate the user (and only for the "/ntlm/auth" URL!).

The big tip is here: if Kerberos cannot authenticate the user, it must redirect to an eZpublish page. The "/user/login" is an arbitrary choice, because the SSO login handler will make redirections before the execution of the user/login script (see next step).

Now, you have to make your SSO login handler, playing with all needed redirections, to manage correctly all possible bounds.

The following SSO login handler is a complete example:

function handleSSOLogin() {
  $ip = $_SERVER["REMOTE_ADDR"];
  $net = $ini->variable( 'NTLMSettings', 'net' );
  $mask = $ini->variable( 'NTLMSettings', 'mask' );

  // tip: (net & mask) == (ip & mask) : ok!
  if ((ip2long($net)&ip2long($mask))==(ip2long($ip)&ip2long($mask))) {

    // 2nd case : /ntlm/auth redirected to first URL, to auth under PHP.
    if ($_SESSION['ntlm_success']=="success") {
      if ( array_key_exists( 'REMOTE_USER', $_SESSION )
             && array_key_exists( 'AUTH_TYPE', $_SESSION ) ) {
        $remoteUser = $_SESSION['REMOTE_USER'];
        $authType = $_SESSION['AUTH_TYPE'];

        eZDebug::writeDebug('#25# user:'.$remoteUser,'');

        $loginParts = explode( '@', $remoteUser );
        $loginName = $loginParts[0];

        // main call of YOUR User handler in NTLM mode
        $user = LOGINCLASS::loginUser($loginName);

        if ( is_object( $user ) ) {
          return $user;
        } else {
          eZDebug::writeDebug('#36# Unable to fetch user','');
          unset($_SESSION['REMOTE_USER']);
          unset($_SESSION['AUTH_TYPE']);
        }
      } else {
        eZDebug::writeDebug('#39# No sso auth performed','');
        unset($_SESSION['REMOTE_USER']);
        unset($_SESSION['AUTH_TYPE']);
      }
      $_SESSION['ntlm_success'] = "failed";
      return false;
    }

    // first case : sso_handler redirection to /ntlm/auth.
    if ($_SERVER['SCRIPT_URL'] == '/ntlm/auth') {
      eZDebug::writeDebug('#47# IP on domain, Kerberos OK.','');
      if (!$_SESSION['ntlm_url']) {
        echo 'Cookies or/and Sessions are not activated.<br/>';
        eZExecution::cleanExit();
      }
      $ntlm_url = $_SESSION['ntlm_url'];
      unset($_SESSION['ntlm_url']);
      $_SESSION['ntlm_success'] = "success";
      $_SESSION['REMOTE_USER'] = $_SERVER['REMOTE_USER'];
      $_SESSION['AUTH_TYPE'] = $_SERVER['AUTH_TYPE'];
      eZHTTPTool::redirect($ntlm_url);
      eZExecution::cleanExit();
    } else if ($_SESSION['ntlm_success'] != "failed") {
      eZDebug::writeDebug('#59# IP on domain, checking NTLM.','');
      $_SESSION['ntlm_url']=$_SERVER['SCRIPT_URL'];
      eZHTTPTool::redirect('/ntlm/auth');
      eZExecution::cleanExit();
    } else {
      eZDebug::writeDebug('#64# IP on domain, Kerberos failed.','');
    }

  } else eZDebug::writeDebug('#67# IP not on domain, Stop.','');

  return false;
}

This script will process like this:

  • First, a test is executed to ensure we are on the right domain (by mask and IP)
  • Then a redirection is done to /ntlm/auth ; we store the original URL typed in the SESSION
  • When /ntlm/auth is called, apache Kerberos module will try to authenticate user
  • if failed, an Apache redirection (by "ErrorDocument 401" param) is done to /user/login
  • in this case, our SSO login handler will redirect to the original URL typed by the user, with a failed state for authentication (stored in the session)
  • the next login handler will try an authentication with a form...
  • if succeeded, our SSO login handler will store user login (given by Kerberos under $_SESSION['REMOTE_USER']) and will redirect to the original URL typed by the user,
  • on this new URL, our SSO login handler will authenticate the given user in the database (you have to implement "LOGINCLASS::loginUser($loginName);" line by yourself)
  • in case of success, login process is terminated, the $user is returned.
  • in case of failure, false is returned to let next login handler try an authentication with a form...

If you have any question, comment this post!

Good luck!

11/12/2009 3:25 pm (UTC)   Xavier Gouley   View entry   Digg!  digg it!   del.icio.us  del.icio.us

xavier gouley

› First Android Developper Challenge over

About two weeks ago, the first ADC is over, and winners are published.

This post will comment few winner applications, positive and negative points on them.

Firstly, I saw in a recent RSS feed that ADC judges are mainly from the Handset Alliance. I think this is quite unfair for some kind of application. Judges are from constructors like HTC, NVidia, Samsung, Telefonica, Motorola, T-mobile *, ASUS, etc... and for a lot of them, they are mobile contructors. By this way, many applications are designed to be winners because of the marketing concept that constructors like to use for selling a mobile. For example, many winners are social networks. I understand that this kind of application will be very used by majority of people (if they have enough money to stay connected to the Internet everytime they use their mobile...), but other applications, that could be really usefull but that are not a very good subject for marketing could be disadvantaged.

A second point that I want to highlight is that in a lot of these winner applications, the user interface is made for a very high resolution. Think that first mobiles using Android won't have such a resolution. In this case, the winner application won't work correctly on many of these phones...

Yet, I was impressed by some of these applications. For example a biometric application called BioWallet that scan eyes for iris based authentication (yes, you will need a very good camera on your mobile now...), or the ability to scan 1D and 2D barcodes.

The past month, I tried the Android SDK, and I enjoyed the easy way to make efficient user interfaces.

The next post I will put on this blog will be about first steps in Android SDK.

The following links talks about the 50 winners of the ADC. See them and imagine what Android will be in few months:

11/12/2009 3:20 pm (UTC)   Xavier Gouley   View entry   Digg!  digg it!   del.icio.us  del.icio.us

xavier gouley

› Jieting launcher released

Hi,

This week, I finished an old personal project on Java platform.

This project, called Jieting Launcher, is a modular engine written in Java, that offers simple interfaces & services between modules. Adding a new module into the application is very easy (like copy a JAR in a folder), and version upgrade is dynamic. This application brings frameworks for developper tasks for Swing, AWT or SWT.

The application is now in beta version, 0.2, and I will follow statistics to know if my idea is appreciated and used.

The given screenshot is an example of my application starting modules, building dependency trees, resolving conflicts between modules and libraries, and finally launching modules. It's a dynamic splash screen: the only UI that is mandatory in the application (all other stuff is in modules).

To make your own module, you just have to follow an Interface, and if you want, include existing other modules (for dependencies), and that's all!

You can access the project through the following link :
SourceForge.net: Jieting launcher

Enjoy!

11/12/2009 3:17 pm (UTC)   Xavier Gouley   View entry   Digg!  digg it!   del.icio.us  del.icio.us

xavier gouley

› eZpublish Templates: Easy access to attributes from unknown class

Hi, today, I want to share a good tip to have access to an object attribute of an unknown class from eZpublish templates. This case is rare, but when you have an object with unknown attribute, or from an unknown PHP class, and you want to access an attribute by its name, if the object does not extends a datatype, the classic "object.attribute" operator in template language cannot work. The problem is that this operator call methods like attributes(), hasAttribute($attr) or attribute($attr) to explore the attributes. In your case, the object has no such methods, you cannot modify the class to add them (for some reasons, for example if the object comes from PHP SOAP), and then you need a wrapper to simulate a datatype.

I propose a DummyDatatype wrapper class, used by a template operator, like this :

class DummyDataType {
    var $Object = false;
    function DummyDataType($object = false) {
        $this->Operators = array( 'ddt' );
        $this->NamedOperators = array(
                'ddt'=> array( 'attribut' => array(
                       'type' => 'Object',
                       'required' => true,
                       'default' => null))
        );
        $this->Object = $object;
    }
    function modify( $tpl, $operatorName, $operatorParameters,
                  $rootNamespace, $currentNamespace,
                  &$operatorValue, $namedParameters) {
        switch ( $operatorName ) {
        case 'ddt':
            $this->Object = ($operatorValue != null)?
                 $operatorValue : $namedParameters['attribut'];
            $operatorValue = $this;
        break;
        default :
            $tpl->warning($operatorName,
                   "Unknown operator '$operatorName'");
        break;
        }
    }
    function operatorList() {
        return $this->Operators;
    }
    function namedParameterPerOperator() {
         return true;
    }
    function namedParameterList() {
         return $this->NamedOperators;
    }
    function attributes() {
         $obj = $this->Object;
         $result = array();
         foreach($obj as $key => $value) {
             $result[] = $key;
         }
         return $result;
        //TODO: test this in all cases (string,integer,...)
    }
    function hasAttribute( $attr ) {
         if ($this->Object == false) return false;
         return isset( $this->Object->$attr );
    }
    function attribute( $attr ) {
         if (isset( $this->Object )) {
             if ( isset( $this->Object->$attr ) )
                 return $this->Object->$attr;
         }
         eZDebug::writeError("Attribute '$attr' does not exist",
                        'DummyDataType::attribute');
         $attributeData = null;
         return $attributeData;
    }
}

With this class, used like a template operator in an extension, you can explore an object, whatever his class,
by calling this:

my_object|ddt('my_attribute').0 {* an array *}

my_object|ddt('sub_object')|ddt('a_datatype_object').content...
{* object containing datatype object, with content attribute *}

This class could be useful for some rare cases, but is a smart solution, so keep a bookmark on it ;)

11/12/2009 3:14 pm (UTC)   Xavier Gouley   View entry   Digg!  digg it!   del.icio.us  del.icio.us

xavier gouley

› Android overview

Today, I wish to share my passion for Android, the user interface of my future mobile phone. Android is like an operating system on a mobile phone, but it is an open source, easy to program, and maintained by the giant Google.

Android is only at the stage of its development, it is thus still difficult to know what will be the final result, but it promises a lot, because built by the best Java developers from all over the world, and leads to creativity by a challenge of $10'000'000...

It runs on Java under an embeded and enhanced JVM, itself running over a linux kernel. Since few months, the SDK is available, with an emulator; many developers communities were formed; the challenge increased creativity and numbers of program tries. Soon, a first giant step will be made by google in the mobile phone world.

I can only advise you to go to throw a glance, as well on the Google workshops as on Youtube to see some basic demonstrations, as “how to create an application like a contact list in about 5 minutes and 15 code lines".

Next Android steps:

  • 14th April 2008: Challenge deadline, end of the first step,
  • 28th/29th May 2008: Google I/O, for much more details about Android

Some interesting links:

RSS/Atom Feeds:

11/12/2009 3:09 pm (UTC)   Xavier Gouley   View entry   Digg!  digg it!   del.icio.us  del.icio.us

community news (ez.no)  eZ systems employee

› The eZ Community activities have moved from http://ez.no/developer to http://share.ez.no

Continuing on addressing more care and dedication to its community, eZ Systems created a dedicated portal for all community-related activities around eZ Publish: http://share.ez.no

02/12/2009 7:09 pm (UTC)   Community news (ez.no)   View entry   Digg!  digg it!   del.icio.us  del.icio.us

sandro groganz

› Commercialization of PHP Software

I’ve just published an article that explains how a PHP-based product can gain a good position in the market and be made appealing to customers by using marketing communication. The focus is on products licensed under an Open Source license. Yet, most of the recommendations also apply to proprietary offerings. The article has initially been published [...]
30/11/2009 4:30 pm (UTC)   Sandro Groganz   View entry   Digg!  digg it!   del.icio.us  del.icio.us

ez projects

› eZ XML Installer Version 0.1.4 released

The first stable version of the eZ XML Installer has just been released.

Please look here for details.

Please look here to download and test the new release.

30/11/2009 3:10 pm (UTC)   eZ Projects   View entry   Digg!  digg it!   del.icio.us  del.icio.us

derick rethans

› Xdebug moved to a new server

Xdebug's CVS server was previously hosted at eZ Systems' office, but as I am leaving soon I needed to move this to a different server. At the same time, I decided to also convert from CVS to SVN. So from now on, there is no more cvs.xdebug.org, but just a svn.xdebug.org. This SVN server doesn't only host Xdebug, but also some of my other projects, such as VLD (opcode dumper to aid PHP engine development), the DBGp specs (debugger protocol as used by Xdebug and ActiveState's debuggers) and my OpenMoko perversions and projects.

Xdebug can now be checked out from SVN with:

svn co svn://svn.xdebug.org/svn/xdebug/xdebug/trunk xdebug

All other Xdebug services (mailinglists, web, e-mail and the bug system) moved to the same server as well. Just be aware that DNS servers might still need updating when you try to access the new services.

27/11/2009 3:42 pm (UTC)   Derick Rethans   View entry   Digg!  digg it!   del.icio.us  del.icio.us

derick rethans

› Xdebug moved to a new server

Xdebug moved to a new server

Xdebug 's CVS server was previously hosted at eZ Systems' office, but as I am leaving soon I needed to move this to a different server. At the same time, I decided to also convert from CVS to SVN. So from now on, there is no more cvs.xdebug.org, but just a svn.xdebug.org. This SVN server doesn't only host Xdebug, but also some of my other projects, such as VLD (opcode dumper to aid PHP engine development), the DBGp specs (debugger protocol as used by Xdebug and ActiveState's debuggers) and my OpenMoko perversions and projects.

Xdebug can now be checked out from SVN with:

svn co svn://svn.xdebug.org/svn/xdebug/xdebug/trunk xdebug

All other Xdebug services (mailinglists, web, e-mail and the bug system) moved to the same server as well. Just be aware that DNS servers might still need updating when you try to access the new services.

27/11/2009 3:42 pm (UTC)   Derick Rethans   View entry   Digg!  digg it!   del.icio.us  del.icio.us

eZ publish™ copyright © 1999-2005 eZ systems as