Handling Authentication

0
70
9 min read

(for more resources related to this topic, see here.)

Understanding Authentication methods

In a world where security on the Internet is such a big issue, the need for great authentication methods is something that cannot be missed. Therefore, Zend Framework 2 provides a range of authentication methods that suits everyone’s needs.

Getting ready

To make full use of this, I recommend a working Zend Framework 2 skeleton application to be set up.

How to do it…

The following is a list of authentication methods—or as they are called adapters—that are readily available in Zend Framework 2. We will provide a small overview of the adapter, and instructions on how you can use it.

The DbTable adapter

Constructing a DbTable adapter is pretty easy, if we take a look at the following constructor:

public function __construct( // The ZendDbAdapterAdapter DbAdapter $zendDb, // The table table name to query on $tableName = null, // The column that serves as 'username' $identityColumn = null, // The column that serves as 'password' $credentialColumn = null, // Any optional treatment of the password before // checking, such as MD5(?), SHA1(?), etcetera $credentialTreatment = null );

The HTTP adapter

After constructing the object we need to define the FileResolver to make sure there are actually user details parsed in.

Depending on what we configured in the accept_schemes option, the FileResolver can either be set as a BasicResolver, a DigestResolver, or both.

Let’s take a quick look at how to set a FileResolver as a DigestResolver or BasicResolver (we do this in the /module/Application/src/Application/Controller/IndexController.php file):

<?php namespace Application; // Use the FileResolver, and also the Http // authentication adapter. use ZendAuthenticationAdapterHttpFileResolver; use ZendAuthenticationAdapterHttp; use ZendMvcControllerAbstractActionController; class IndexController extends AbstractActionController { public function indexAction() { // Create a new FileResolver and read in our file to use // in the Basic authentication $basicResolver = new FileResolver(); $basicResolver->setFile( '/some/file/with/credentials.txt' ); // Now create a FileResolver to read in our Digest file $digestResolver = new FileResolver(); $digestResolver->setFile( '/some/other/file/with/credentials.txt' ); // Options doesn't really matter at this point, we can // fill them in to anything we like $adapter = new Http($options); // Now set our DigestResolver/BasicResolver, depending // on our $options set $adapter->setBasicResolver($basicResolver); $adapter->setDigestResolver($digestResolver); } }

How it works…

After two short examples, let’s take a look at the other adapters available.

The DbTable adapter

Let’s begin with probably the most used adapter of them all, the DbTable adapter. This adapter connects to a database and pulls the requested username/password combination from a table and, if all went well, it will return to you an identity, which is nothing more than the record that matched the username details.

To instantiate the adapter, it requires a ZendDbAdapterAdapter in its constructor to connect with the database with the user details; there are also a couple of other options that can be set. Let’s take a look at the definition of the constructor:

The second (tableName) option speaks for itself as it is just the table name, which we need to use to get our users, the third and the fourth (identityColumn, credentialColumn) options are logical and they represent the username and password (or what we use) columns in our table. The last option, the credentialTreatment option, however, might not make a lot of sense.

The credentialTreatment tells the adapter to treat the credentialColumn with a function before trying to query it. Examples of this could be to use the MD5 (?) function, PASSWORD (?), or SHA1 (?) function, if it was a MySQL database, but obviously this can differ per database as well. To give a small example on how the SQL can look like (the actual adapter builds this query up differently) with and without a credential treatment, take a look at the following examples:

With credential treatment:

SELECT * FROM `users` WHERE `username` = 'some_user' AND `password`
= MD5('some_password');

Without credential treatment:

SELECT * FROM `users` WHERE `username`
= 'some_user' AND `password` = 'some_password';

When defining the treatment we should always include a question mark for where the password needs to come, for example, MD5 (?) would create MD5 (‘some_password’), but without the question mark it would not insert the password.

Lastly, instead of giving the options through the constructor, we can also use the setter methods for the properties: setTableName(), setIdentityColumn(), setCredentialColumn(), and setCredentialTreatment().

The HTTP adapter

The HTTP authentication adapter is an adapter that we have probably all come across at least once in our Internet lives. We can recognize the authentication when we go to a website and there is a pop up showing where we can fill in our usernames and passwords to continue.

This form of authentication is very basic, but still very effective in certain implementations, and therefore, a part of Zend Framework 2. There is only one big massive but to this authentication, and that is that it can (when using the basic authentication) send the username and password clear text through the browser (ouch!).

There is however a solution to this problem and that is to use the Digest authentication, which is also supported by this adapter.

If we take a look at the constructor of this adapter, we would see the following code line:

public function __construct(array $config);

The constructor accepts a load of keys in its config parameter, which are as follows:

  • accept_schemes: This refers to what we want to accept authentication wise; this can be basic, digest, or basic digest.
  • realm: This is a description of the realm we are in, for example Member’s area. This is for the user only and is only to describe what the user is logging in for.
  • digest_domains: These are URLs for which this authentication is working for. So if a user logs in with his details on any of the URLs defined, they will work. The URLs should be defined in a space-separated (weird, right?) list, for example /members/area /members/login.
  • nonce_timeout: This will set the number of seconds the nonce (the hash users login with when we are using Digest authentication) is valid. Note, however, that nonce tracking and stale support are not implemented in Version 2.2 yet, which means it will authenticate again every time the nonce times out.
  • use_opaque: This is either true or false (by default is true) and tells our adapter to send the opaque header to the client. The opaque header is a string sent by the server, which needs to be returned back on authentication. This does not work sometimes on Microsoft Internet Explorer browsers though, as they seem to ignore that header. Ideally the opaque header is an ever-changing string, to reduce predictability, but ZF 2 doesn’t randomize the string and always returns the same hash.
  • algorithm: This includes the algorithm to use for the authentication, it needs to be a supported algorithm that is defined in the supportedAlgos property. At the moment there is only MD5 though.
  • proxy_auth: This boolean (by default is false) tells us if the authentication used is a proxy Authentication or not.

It should be noted that there is a slight difference in files when using either Digest or Basic. Although both files have the same layout, they cannot be used interchangeably as the Digest requires the credentials to be MD5 hashed, while the Basic requires the credentials to be plain text. There should also always be a new line after every credential, meaning that the last line in the credential file should be empty.

The layout of a credential file is as follows:

username:realm:credentials

For example:

some_user:My Awesome Realm:clear text password

Instead of a FileResolver, one can also use the ApacheResolver which can be used to read out htpasswd generated files, which comes in handy when there is already such a file in place.

The Digest adapter

The Digest adapter is basically the Http adapter without any Basic authentication. As the idea behind it is the same as the Http adapter, we will just go on and talk about the constructor, as that is a bit different in implementation:

public function __construct($filename = null, $realm = null, $identity = null, $credential = null);

As we can see the following options can be set when constructing the object:

  • filename: This is the direct filename of the file to use with the Digest credentials, so no need to use a FileResolver with this one.
  • realm: This identifies to the user what he/she is logging on to, for example My Awesome Realm or The Dragonborn’s lair. As we are immediately trying to log on when constructing this, it does need to correspond with the credential file.
  • identity: This is the username we are trying to log on with, and again it needs to resemble a user that is defined in the credential file to work.
  • credential: This is the Digest password we try to log on with, and this again needs to match the password exactly like the one in the credential file.

We can then, for example, just run $digestAdapter->getIdentity() to find out if we are successfully authenticated or not, resulting in NULL if we are not, and resulting in the identity column value if we are.

The LDAP adapter

Using the LDAP authentication is obviously a little more difficult to explain, so we will not go in to that full as that would take quite a while. What we will do is show the constructor of the LDAP adapter and explain its various options. However, if we want to know more about setting up an LDAP connection, we should take a look at the documentation of ZF2, as it is explained in there very well:

public function __construct(array $options = array(), $identity = null, $credential = null);

The options parameter in the construct refers to an array of configuration options that are compatible with the ZendLdapLdap configuration. There are literally dozens of options that can be set here so we advice to go and look at the LDAP documentation of ZF2 to know more about that. The next two parameters identity and credential are respectively the username and password again, so that explains itself really.

Once you have set up the connection with the LDAP there isn’t much left to do but to get the identity and see whether we were successfully validated or not.

About Authentication

Authentication in Zend Framework 2 works through specific adapters, which are always an implementation of the ZendAuthenticationAdapterAdapterInterface and thus, always provides the methods defined in there. However, the methods of Authentication are all different, and strong knowledge of the methods displayed previously is always a requirement. Some work through the browser, like the Http and Digest adapter, and others just require us to create a whole implementation like the LDAP and the DbTable adapter.

LEAVE A REPLY

Please enter your comment!
Please enter your name here