New User Email Verification with Spring, the Code

In our last post we walked through the User Registration process with Email Verification. Here’s the sample verification email we sent.

As promised, in this post we’ll go behind-the-scenes and look at how we use Spring to manage the moving parts.

A New User_Data Table

We’ll begin in the database where we added a user_data table to extend the users table, with a UserData Model with a @OneToOne relationship with our core User Model. (As you can see, we have plans for additional login and registration-related features in the future.) The primary field used with Email Verification is approved_datetime. With Email Verification enabled, when a user completes the Registration Form the enabled field of our users table is set to FALSE and our user_data.approved_datetime field is NULL.

Catching Authentication Issues with an AuthenticationFailureHandler Bean

This is a pretty cool aspect of customizing User Registration, where we catch an Authentication Failure with a Spring AuthenticationFailureHandler Bean.

Before looking at the AuthenticationFailureHandler we need to begin in the CurrentUserDetailsService because this is our primary SecurityConfiguration User Authentication class. When we load the User we check the isEnabled() status field which we initially set to FALSE on /registration/{POST}. If FALSE we throw a Spring DisabledException.

Now in our Spring Authentication Handler we test for that Exception and respond with an appropriate flash message on the User Login form. We load the user from the Login form username field at (1) and if the Exception Message tells us the User is Disabled we can see if the ApprovedDatetime() value is NULL. We can perform other tests here based on the User IsEnabled() Exception with other UserData object properties.

Here’s the result of that response.

One more reminder about using an Authentication Failure Handler is that it must be added to your Web Security configuration.

Responding to the Email Verification Link

We set the User.IsEnabled property to FALSE on registration before sending the Verification Email. Here’s what happens when the user clicks on the Link in the Email. The url is /users/verify/[USERKEY]. Every user has a unique UserKey property of between 15 and 20 characters stored in their User record.

With the following result.

The Tests

We pretty much covered the moving parts of User Registration with Email Verification. The following tests confirm the essential actions of user.isEnabled() and userData.approvedDateTime().

First MVC UserController /registration/{POST} where the user is not enabled and approvedDateTime is NULL.

At the Service Level in the JPA module we see the same results.

Source Code Notes for this Post

All source code discussed in this post can be found in my NixMash Spring GitHub repo and viewed online here.