(for more resources related to this topic, see here.)
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.
To make full use of this, I recommend a working Zend Framework 2 skeleton application to be set up.
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.
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 );
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); } }
After two short examples, let's take a look at the other adapters available.
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 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:
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 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:
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.
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.
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.