How to block users with the Ma27ApiKeyAuthenticationBundle

I’ve showed in the previous blog post how to implement API key authentications against a REST API using Ma27ApiKeyAuthenticationBundle. The workflow of the login is quite simple, but should be extendable for certain business specific requirements of the applications using that bundle. In this blog post I’ll show how to deal with the event system of the login workflow by using a simple example in order to hook into the process with custom listeners.

A complete overview of all events provided by this bundle can be found in the docs.

Preparation

Before starting with the actual code, we need a user model for our purposes.

In this case the only pieces of code being displayed are those which are relevant for this tutorial.

Event listener

The login directive contains several events that can be used by applications to hook into certain processes:

  • ma27_api_key_authentication.credential_failure which will be triggered if the credential validation fails
  • ma27_api_key_authentication.authentication which will be triggered if the credential validation succeeds
NOTE: the ma27_api_key_authentication.authentication will be triggered before the token generation since this event can be used to run further validation processes which could fail the login, therefore it is safer to generate the api key afterwords.

As described above, the ma27_api_key_authentication.authentication event can be used to fail the authentication process. This can be done by throwing a CredentialException which is catched in the controller and transformed into a 401 Unauthorized response. If the CredentialException doesn’t contain a message, Credentials refused! is the default one which will be used in the response.

In our case we need a class listening to ma27_api_key_authentication.authentication in order to check whether the user is blocked or not.

The controller attempts to translate every message delivered by the CredentialException using the messages catalogue of Symfony’s translation component:

If a blocked user would now try to login, the 401 response would look like this:

{
"message": "You're blocked!"
}