Path

ez components / documentation / api reference / 2007.1 / authentication


eZ Components 2007.1

Authentication

[ Tutorial ] [ Security ] [ Class tree ] [ Element index ] [ ChangeLog ] [ Credits ]

Introduction

Description

The purpose of the Authentication component is to provide support for different means of identification and authentication of users using different providers and protocols.

Class overview

An overview of the most important classes in the Authentication component.

Base classes

ezcAuthentication
Main class of Authentication. It is a container for authentication filters, which will be run in sequence. The method run() returns true or false depending on the success of the authentication filters.
ezcAuthenticationCredentials
Structure which holds user credentials. Types are id credentials (ezcAuthenticationIdCredentials) and id + password credentials (ezcAuthenticationPasswordCredentials).
ezcAuthenticationSession
Used to store the authenticated username and the timestamp between requests.

Authentication filters

ezcAuthenticationDatabaseFilter
Filter to authenticate against a database. Uses a database instance provided by the Database component (via the ezcDbInstance::get() function). It depends on the Database component, so it is implemented in the the tie-in component AuthenticationDatabaseTiein.
ezcAuthenticationGroupFilter
Container filter for 2 or more filters. Depending on configuration, at least one filter needs to succeed in order for the group to succeed, or all filters need to succeed in order for the group to succeed.
ezcAuthenticationHtpasswdFilter
Filter to authenticate against a htpasswd password file. Supports the same encryption methods as the Unix command htpasswd, and the encryption method is detected automatically from the file.
ezcAuthenticationLdapFilter
Filter to authenticate against an LDAP directory. For now the password can be only in plain text. It depends on the PHP ldap extension.
ezcAuthenticationOpenidFilter
Filter to authenticate against OpenID. For now the OpenID version 1.1 is supported.
ezcAuthenticationTokenFilter
Filter used to implement CAPTCHA tests. It basically compares the server generated token with the value entered by the user, using a specified hashing callback function.

Stores

OpenID uses a store to hold the generated nonces and the associations (in "smart" mode). If there is no store specified, then nonces are not checked.

ezcAuthenticationOpenidStore
Abstract class from which the different stores inherit.
ezcAuthenticationOpenidFileStore
Uses file storage. Nonces are stored in files named after the nonce itself, and associations are stored in files named after the OpenID provider with which the association is made. Currently is the only store implemented.

General authentication

Stateless authentication

The general template for authentication is:

  • get the user credentials (eg. in a ezcAuthenticationPasswordCredentials object)
  • create an object of class ezcAuthentication and pass the credentials object to it
  • add authentication filters to the authentication object with addFilter()
  • call the run() method of the authentication object
  • call the getStatus() method of the authentication object and analyse it

The following example demonstrates the above steps.

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. 
  4. $credentials = new ezcAuthenticationPasswordCredentials'jan.modaal''b1b3773a05c0ed0176787a4f1574ff0075f7521e' );
  5. $authentication = new ezcAuthentication$credentials );
  6. $authentication->addFilter( new ezcAuthenticationHtpasswdFilter'/etc/htpasswd' ) );
  7. // add more filters if needed
  8. if ( !$authentication->run() )
  9. {
 10.     // authentication did not succeed, so inform the user
 11.     $status $authentication->getStatus();
 12.     $err = array(
 13.             'ezcAuthenticationHtpasswdFilter=> array(
 14.                 ezcAuthenticationHtpasswdFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
 15.                 ezcAuthenticationHtpasswdFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
 16.                 )
 17.             );
 18.     foreach ( $status as $line )
 19.     {
 20.         list( $key$value ) = each$line );
 21.         echo $err[$key][$value] . "\n";
 22.     }
 23. }
 24. else
 25. {
 26.     // authentication succeeded, so allow the user to see his content
 27. }
 28. ?>

First, a credentials object is created with username jan.modaal and password 'b1b3773a05c0ed0176787a4f1574ff0075f7521e' (sha1() hash).

An authentication object is created using the credentials object, and a htpasswd filter (using the /etc/htpasswd file) is added to it.

After running the authentication (line 8), if the username and the password do not pass through the htpasswd filter, then the credentials are incorrect and the user must be informed. The getStatus() method is used for this. The values in the status returned must be cycled through and for each value a response is created for the user ("Username incorrect", "Password incorrect").

If run() returned true (line 24) then the user is logged-in and he can see his content.

Using session

The following example shows how to use the session class to store authentication information (username and timestamp) between requests.

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. 
  4. // no headers should be sent before calling $session->start()
  5. $session = new ezcAuthenticationSession();
  6. $session->start();
  7. $user = isset( $_POST['user'] ) ? $_POST['user'] : $session->load();
  8. $password = isset( $_POST['password'] ) ? $_POST['password'] : null;
  9. $credentials = new ezcAuthenticationPasswordCredentials$user$password );
 10. $authentication = new ezcAuthentication$credentials );
 11. $authentication->session $session;
 12. $authentication->addFilter( new ezcAuthenticationHtpasswdFilter'/etc/htpasswd' ) );
 13. // add other filters if needed
 14. if ( !$authentication->run() )
 15. {
 16.     // authentication did not succeed, so inform the user
 17.     $status $authentication->getStatus();
 18.     $err = array(
 19.             'ezcAuthenticationHtpasswdFilter=> array(
 20.                 ezcAuthenticationHtpasswdFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
 21.                 ezcAuthenticationHtpasswdFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
 22.                 ),
 23.             'ezcAuthenticationSession=> array(
 24.                 ezcAuthenticationSession::STATUS_EMPTY => '',
 25.                 ezcAuthenticationSession::STATUS_EXPIRED => 'Session expired'
 26.                 )
 27.             );
 28.     foreach ( $status as $line )
 29.     {
 30.         list( $key$value ) = each$line );
 31.         echo $err[$key][$value] . "\n";
 32.     }
 33. }
 34. else
 35. {
 36.     // authentication succeeded, so allow the user to see his content
 37. }
 38. ?>

A session class is created and used to start the PHP session. The username and password (provided by the user through a POST form) are fetched and used to create a credentials object.

An authentication object is created using the credentials object, and the session class is added to the authentication object. In addition an htpasswd filter (using the /etc/htpasswd file) is added to the authentication object.

After running the authentication (line 14), if the username and the password do not pass through the session class or the htpasswd filter, then the credentials are incorrect and the user must be informed. The getStatus() method is used for this. The values in the status returned must be cycled through and for each value a response is created for the user ("Username incorrect", "Password incorrect", "Session expired").

If run() returned true (line 34) then the user is logged-in and he can see his content.

Authentication filters

Group

The following example shows how to use a group filter to authenticate against EITHER a database or an LDAP directory.

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. 
  4. $credentials = new ezcAuthenticationPasswordCredentials'jan.modaal''qwerty' );
  5. 
  6. // create a database filter
  7. $database = new ezcAuthenticationDatabaseInfoezcDbInstance::get(), 'users', array( 'user''password' ) );
  8. $databaseFilter = new ezcAuthenticationDatabaseFilter$database );
  9. 
 10. // create an LDAP filter
 11. $ldap = new ezcAuthenticationLdapInfo'localhost''uid=%id%''dc=example,dc=com'389 );
 12. $ldapFilter = new ezcAuthenticationLdapFilter$ldap );
 13. $authentication = new ezcAuthentication$credentials );
 14. 
 15. // use the database and LDAP filters in paralel (only one needs to succeed in
 16. // order for the user to be authenticated
 17. $authentication->addFilter( new ezcAuthenticationGroupFilter( array( $databaseFilter$ldapFilter ) ) );
 18. // add more filters if needed
 19. if ( !$authentication->run() )
 20. {
 21.     // authentication did not succeed, so inform the user
 22.     $status $authentication->getStatus();
 23.     $err = array(
 24.             'ezcAuthenticationLdapFilter=> array(
 25.                 ezcAuthenticationLdapFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
 26.                 ezcAuthenticationLdapFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
 27.                 ),
 28.             'ezcAuthenticationDatabaseFilter=> array(
 29.                 ezcAuthenticationDatabaseFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
 30.                 ezcAuthenticationDatabaseFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
 31.                 )
 32.             );
 33.     foreach ( $status as $line )
 34.     {
 35.         list( $key$value ) = each$line );
 36.         echo $err[$key][$value] . "\n";
 37.     }
 38. }
 39. else
 40. {
 41.     // authentication succeeded, so allow the user to see his content
 42. }
 43. ?>

First, a credentials object is created with username 'jan.modaal' and password 'qwerty'.

An authentication object is created using the credentials object. A group filter is added to it, consisting of a Database filter and an LDAP filter.

After running the authentication (line 19), if the username and the password do not pass through any of the filters in the group, then the credentials are incorrect and the user must be informed. The getStatus() method is used for this. The values in the status returned must be cycled through and for each value a response is created for the user ("Username incorrect", "Password incorrect").

If run() returned true (line 39) then the user is logged-in and he can see his content.

Htpasswd

The following example shows how to authenticate against an htpasswd file.

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. 
  4. $credentials = new ezcAuthenticationPasswordCredentials'jan.modaal''b1b3773a05c0ed0176787a4f1574ff0075f7521e' );
  5. $authentication = new ezcAuthentication$credentials );
  6. $authentication->session = new ezcAuthenticationSession();
  7. $authentication->addFilter( new ezcAuthenticationHtpasswdFilter'/etc/htpasswd' ) );
  8. // add other filters if needed
  9. if ( !$authentication->run() )
 10. {
 11.     // authentication did not succeed, so inform the user
 12.     $status $authentication->getStatus();
 13.     $err = array(
 14.             'ezcAuthenticationHtpasswdFilter=> array(
 15.                 ezcAuthenticationHtpasswdFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
 16.                 ezcAuthenticationHtpasswdFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
 17.                 )
 18.             );
 19.     foreach ( $status as $line )
 20.     {
 21.         list( $key$value ) = each$line );
 22.         echo $err[$key][$value] . "\n";
 23.     }
 24. }
 25. else
 26. {
 27.     // authentication succeeded, so allow the user to see his content
 28. }
 29. ?>

First, a credentials object is created with username jan.modaal and password 'b1b3773a05c0ed0176787a4f1574ff0075f7521e' (sha1() hash).

An authentication object is created using the credentials object, and a htpasswd filter (using the /etc/htpasswd file) is added to it.

After running the authentication (line 9), if the username and the password do not pass through the htpasswd filter, then the credentials are incorrect and the user must be informed. The getStatus() method is used for this. The values in the status returned must be cycled through and for each value a response is created for the user ("Username incorrect", "Password incorrect").

If run() returned true (line 25) then the user is logged-in and he can see his content.

LDAP

The following example shows how to authenticate agains an LDAP directory.

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. 
  4. $credentials = new ezcAuthenticationPasswordCredentials'jan.modaal''qwerty' );
  5. $ldap = new ezcAuthenticationLdapInfo'localhost''uid=%id%''dc=example,dc=com'389 );
  6. $authentication = new ezcAuthentication$credentials );
  7. $authentication->addFilter( new ezcAuthenticationLdapFilter$ldap ) );
  8. // add more filters if needed
  9. if ( !$authentication->run() )
 10. {
 11.     // authentication did not succeed, so inform the user
 12.     $status $authentication->getStatus();
 13.     $err = array(
 14.             'ezcAuthenticationLdapFilter=> array(
 15.                 ezcAuthenticationLdapFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
 16.                 ezcAuthenticationLdapFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
 17.                 )
 18.             );
 19.     foreach ( $status as $line )
 20.     {
 21.         list( $key$value ) = each$line );
 22.         echo $err[$key][$value] . "\n";
 23.     }
 24. }
 25. else
 26. {
 27.     // authentication succeeded, so allow the user to see his content
 28. }
 29. ?>

First, a credentials object is created with username jan.modaal and password 'qwerty'.

An authentication object is created using the credentials object, and an LDAP filter is added to it. The $ldap structure specifies the LDAP host (localhost), the format of the directory entry (%id% is a placeholder which will be replaced by the actual value at bind time), the base of the directory entry ('dc=example,dc=com') and the port on which to connect to the host (389).

After running the authentication (line 7), if the username and the password do not pass through the LDAP filter, then the credentials are incorrect and the user must be informed. The getStatus() method is used for this. The values in the status returned must be cycled through and for each value a response is created for the user ("Username incorrect", "Password incorrect").

If run() returned true (line 34) then the user is logged-in and he can see his content.

OpenID

OpenID has 2 modes of operation: dumb and smart. These modes define the way the consumer (the application server, on which the Components run) is communicating with the OpenID provider (another server where users authenticate with their OpenID username and password; there are many of these and users can register on which one they want).

Dumb mode (stateless)

In this mode there are 3 http requests:

Discovery
The consumer requests the URL which the user entered and finds out the URL of the provider.
openid.checkid_setup
The consumer redirects the browser to the provider, so that the user can enter his username and password to the provider. The provider then redirects back to the consumer.
openid.check_authentication
The consumer sends to the provider the values received in step 2 and receives the information if the user is authenticated or not.

Smart mode (keeping state)

In this mode there are also 3 http requests, but only 2 every time and 1 request from time to time:

Discovery
Same as in dumb mode.
openid.checkid_setup
Same as in dumb mode, but the handle associated with the shared secret is sent as well.

The extra request (which is done from time to time) is:

openid.associate
The consumer and the provider establish a shared secret, which the consumer uses when it redirects in step 2, and it will use the same secret for all requests to the same provider. Step 3 (openid.check_authentication) is not required anymore. The shared secret has a timeout period, so it must be renewed from time to time.

OpenID "dumb" (stateless) mode

The following example shows how to authenticate against OpenID in "dumb" (stateless) mode.

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. 
  4. // no headers should be sent before calling $session->start()
  5. $session = new ezcAuthenticationSession();
  6. $session->start();
  7. 
  8. $url = isset( $_GET['openid_identifier'] ) ? $_GET['openid_identifier'] : $session->load();
  9. $action = isset( $_GET['action'] ) ? strtolower$_GET['action'] ) : null;
 10. 
 11. $credentials = new ezcAuthenticationIdCredentials$url );
 12. $authentication = new ezcAuthentication$credentials );
 13. $authentication->session $session;
 14. 
 15. if ( $action === 'logout' )
 16. {
 17.     $session->destroy();
 18. }
 19. else
 20. {
 21.     $filter = new ezcAuthenticationOpenidFilter();
 22.     $authentication->addFilter$filter );
 23. }
 24. 
 25. if ( !$authentication->run() )
 26. {
 27.     // authentication did not succeed, so inform the user
 28.     $status $authentication->getStatus();
 29.     $err = array(
 30.              'ezcAuthenticationOpenidFilter=> array(
 31.                  ezcAuthenticationOpenidFilter::STATUS_SIGNATURE_INCORRECT => 'OpenID said the provided identifier was incorrect',
 32.                  ezcAuthenticationOpenidFilter::STATUS_CANCELLED => 'The OpenID authentication was cancelled',
 33.                  ezcAuthenticationOpenidFilter::STATUS_URL_INCORRECT => 'The identifier you provided is invalid'
 34.                  ),
 35.              'ezcAuthenticationSession=> array(
 36.                  ezcAuthenticationSession::STATUS_EMPTY => '',
 37.                  ezcAuthenticationSession::STATUS_EXPIRED => 'Session expired'
 38.                  )
 39.              );
 40.     foreach ( $status as $line )
 41.     {
 42.         list( $key$value ) = each$line );
 43.         echo $err[$key][$value] . "\n";
 44.     }
 45. ?>
 46. Please login with your OpenID identifier (an URL, eg. www.example.com or http://www.example.com):
 47. <form method="GET" action="">
 48. <input type="hidden" name="action" value="login" />
 49. <img src="http://openid.net/login-bg.gif" /> <input type="text" name="openid_identifier" />
 50. <input type="submit" value="Login" />
 51. </form>
 52. 
 53. <?php
 54. }
 55. else
 56. {
 57. ?>
 58. 
 59. You are logged-in as <b><?php echo $url?></b> | <a href="?action=logout">Logout</a>
 60. 
 61. <?php
 62. }
 63. ?>

A session class is created and used to start the PHP session. The OpenID identifier (provided by the user through a GET form) is fetched and used to create a credentials object. On subsequent requests to the page, the token is loaded from session instead of the GET form. OpenID specifications recommend the name 'openid_identifier' for the text field of the form in which users type their OpenID identifier (so that browser can prefill the field if user chooses this).

An authentication object is created using the credentials object, and the session handler is added to it.

If the user is at logout (line 15), then the session is destroyed, which means the user will see the login form.

If the user is not at logout (line 19), then an OpenID filter is created with the credentials object.

After running the authentication (line 25), if the OpenID server did not authorize the identifier, then the credentials are incorrect and the user must be informed. The getStatus() method is used for this. The values in the status returned must be cycled through and for each value a response is created for the user ("Signature incorrect", "Session expired"). At line 46 a simple HTML form is displayed, as example. The form displays the OpenID logo (as suggested by the OpenID specifications).

If run() returned true (line 55) then the user is logged-in and he can see his content. Line 59 contains an example of how to implement a logout option for the application.

OpenID "smart" (stateful) mode

The following example shows how to authenticate against OpenID in "smart" (stateful) mode.

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. 
  4. // no headers should be sent before calling $session->start()
  5. $session = new ezcAuthenticationSession();
  6. $session->start();
  7. 
  8. $url = isset( $_GET['openid_identifier'] ) ? $_GET['openid_identifier'] : $session->load();
  9. $action = isset( $_GET['action'] ) ? strtolower$_GET['action'] ) : null;
 10. 
 11. $credentials = new ezcAuthenticationIdCredentials$url );
 12. $authentication = new ezcAuthentication$credentials );
 13. $authentication->session $session;
 14. 
 15. if ( $action === 'logout' )
 16. {
 17.     $session->destroy();
 18. }
 19. else
 20. {
 21.     $options = new ezcAuthenticationOpenidOptions();
 22.     $options->mode ezcAuthenticationOpenidFilter::MODE_SMART;
 23.     $options->store = new ezcAuthenticationOpenidFileStore'/tmp/store' );
 24.     $filter = new ezcAuthenticationOpenidFilter$options );
 25.     $authentication->addFilter$filter );
 26. }
 27. 
 28. if ( !$authentication->run() )
 29. {
 30.     // authentication did not succeed, so inform the user
 31.     $status $authentication->getStatus();
 32.     $err = array(
 33.              'ezcAuthenticationOpenidFilter=> array(
 34.                  ezcAuthenticationOpenidFilter::STATUS_SIGNATURE_INCORRECT => 'OpenID said the provided identifier was incorrect',
 35.                  ezcAuthenticationOpenidFilter::STATUS_CANCELLED => 'The OpenID authentication was cancelled',
 36.                  ezcAuthenticationOpenidFilter::STATUS_URL_INCORRECT => 'The identifier you provided is invalid'
 37.                  ),
 38.              'ezcAuthenticationSession=> array(
 39.                  ezcAuthenticationSession::STATUS_EMPTY => '',
 40.                  ezcAuthenticationSession::STATUS_EXPIRED => 'Session expired'
 41.                  )
 42.              );
 43.     foreach ( $status as $line )
 44.     {
 45.         list( $key$value ) = each$line );
 46.         echo $err[$key][$value] . "\n";
 47.     }
 48. ?>
 49. Please login with your OpenID identifier (an URL, eg. www.example.com or http://www.example.com):
 50. <form method="GET" action="">
 51. <input type="hidden" name="action" value="login" />
 52. <img src="http://openid.net/login-bg.gif" /> <input type="text" name="openid_identifier" />
 53. <input type="submit" value="Login" />
 54. </form>
 55. 
 56. <?php
 57. }
 58. else
 59. {
 60. ?>
 61. 
 62. You are logged-in as <b><?php echo $url?></b> | <a href="?action=logout">Logout</a>
 63. 
 64. <?php
 65. }
 66. ?>

The only differences between this example and the one in the previous section is defining the mode of the OpenID filter, and defining a store (here: a file store) which will hold the associations. In addition the store will also hold the nonces which are used to prevent replay attacks.

Token

The following example shows how to create a CAPTCHA test. The example is divided into 2 parts: the initial request (where the user sees the CAPTCHA image and enters the characters he sees in a form) and the follow-up request (after the user submits the form).

On the initial request:

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. 
  4. // generate a token and save it in the session or in a file/database
  5. $pattern "1234567890abcdefghijklmnopqrstuvwxyz";
  6. $token  "";
  7. for( $i 1$i <= $i++ )
  8. {
  9.     $token .= $pattern{rand036 )};
 10. }
 11. $encryptedToken sha1$token );
 12. 
 13. // save the $encryptedToken in the session
 14. session_start();
 15. $_SESSION['encryptedToken'] = $encryptedToken;
 16. 
 17. // also generate a distorted image which contains the symbols from $token and use it
 18. ?>

A 6 characters random token is created and encrypted using sha1(). The token is saved in the session to be available in the follow-up request. An image must be generated from the unencrypted token to be displayed to the user.

On the follow-up request:

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. 
  4. // load the $encryptedToken as it was generated on a previous request
  5. session_start();
  6. $encryptedToken = isset( $_SESSION['encryptedToken'] ) ? $_SESSION['encryptedToken'] : null;
  7. 
  8. // also load the value entered by the user in response to the CAPTCHA image
  9. $captcha = isset( $_POST['captcha'] ) ? $_POST['captcha'] : null;
 10. 
 11. $credentials = new ezcAuthenticationIdCredentials$captcha );
 12. $authentication = new ezcAuthentication$credentials );
 13. $authentication->addFilter( new ezcAuthenticationTokenFilter$encryptedToken'sha1' ) );
 14. if ( !$authentication->run() )
 15. {
 16.     // CAPTCHA was incorrect, so inform the user to try again, eventually
 17.     // by generating another token and CAPTCHA image
 18. }
 19. else
 20. {
 21.     // CAPTCHA was correct, so let the user send his spam or whatever
 22. }
 23. ?>

The token generated on the initial request is fetched from the session, and the CAPTCHA value entered by the user is fetched from the POST request.

A credentials object is created from the CAPTCHA value, and it is used to create an authentication object.

A Token filter is created from the stored encrypted token value, and it is added to the authentication object. The second argument of the Token constructor indicates that the CAPTCHA value will be hashed with sha1() before comparing it with the token value.

After calling run() on the authentication object (line 14), if the token and CAPTCHA values don't match, then the CAPTCHA test was incorrect. The developer decides how to handle this situation (user tries again, user is banned, etc).

If the values match (line 19) then it means the user passed the CAPTCHA test (or the bots managed to OCR the image).

TypeKey

The following example shows how to authenticate against TypeKey.

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. 
  4. // no headers should be sent before calling $session->start()
  5. $session = new ezcAuthenticationSession();
  6. $session->start();
  7. 
  8. // $token is used as a key in the session to store the authenticated state between requests
  9. $token = isset( $_GET['token'] ) ? $_GET['token'] : $session->load();
 10. 
 11. $credentials = new ezcAuthenticationIdCredentials$token );
 12. $authentication = new ezcAuthentication$credentials );
 13. $authentication->session $session;
 14. 
 15. $filter = new ezcAuthenticationTypekeyFilter();
 16. $authentication->addFilter$filter );
 17. // add other filters if needed
 18. 
 19. if ( !$authentication->run() )
 20. {
 21.     // authentication did not succeed, so inform the user
 22.     $status $authentication->getStatus();
 23.     $err = array(
 24.              'ezcAuthenticationTypekeyFilter=> array(
 25.                  ezcAuthenticationTypekeyFilter::STATUS_SIGNATURE_INCORRECT => 'Signature returned by TypeKey is incorrect',
 26.                  ezcAuthenticationTypekeyFilter::STATUS_SIGNATURE_EXPIRED => 'The signature returned by TypeKey expired'
 27.                  ),
 28.              'ezcAuthenticationSession=> array(
 29.                  ezcAuthenticationSession::STATUS_EMPTY => '',
 30.                  ezcAuthenticationSession::STATUS_EXPIRED => 'Session expired'
 31.                  )
 32.              );
 33.     foreach ( $status as $line )
 34.     {
 35.         list( $key$value ) = each$line );
 36.         echo $err[$key][$value] . "\n";
 37.     }
 38. ?>
 39. <form method="GET" action="https://www.typekey.com/t/typekey/login" onsubmit="document.getElementById('_return').value += '?token=' + document.getElementById('t').value;">
 40. TypeKey token: <input type="text" name="t" id="t" />
 41. <input type="hidden" name="_return" id="_return" value="http://localhost/typekey.php" />
 42. <input type="submit" />
 43. </form>
 44. <?php
 45. }
 46. else
 47. {
 48.     // authentication succeeded, so allow the user to see his content
 49.     echo "<b>Logged-in</b>";
 50. }
 51. ?>

A session class is created and used to start the PHP session. The TypeKey token (provided by the user through a GET form) is fetched and used to create a credentials object. On subsequent requests to the page, the token is loaded from session instead of the GET form.

An authentication object is created using the credentials object, and a TypeKey filter is added to it, along with the session class.

After running the authentication (line 19), if the TypeKey server did not authorize the token, then the credentials are incorrect and the user must be informed. The getStatus() method is used for this. The values in the status returned must be cycled through and for each value a response is created for the user ("Signature incorrect", "Session expired"). At line 39 an HTML form is displayed, as example on how to attach the TypeKey token to the _return hidded field which will be sent to the TypeKey server.

If run() returned true (line 46) then the user is logged-in and he can see his content.

Securing applications

Securing applications - A guide to improve the security of online applications. It is not exhaustive, but it provides solutions against common attacks.

Last updated: Thu, 01 Nov 2007