Tuesday, September 20, 2022

Spring Security With Jdbc Authentication Using JAVA Configuration

JAVA,Dispatcher Servlet,Spring Framework,Spring Filter,Spring Security,programming,software development,technology,spring boot
In our previous tutorial, we learned how to configure a custom login page with pre-defined hard-cored user credentials in place of the built-in login page of Spring Security. In this tutorial, we'll learn how to secure a Spring MVC application using Jdbc Authentication along with a custom login page. So in this case, user credentials would not be configured in any configuration file, but rather those would be stored in the database table.

In the basic Spring Security tutorial, we configured user credentials and roles in the ApplicationSecutiryConfiguration class. But now we are going to put user credentials and roles in the database. So we need to tell Spring Security to read that information from the database and on the other hand,   Spring Security also can read that information from the database. 

So, we must follow Spring Security's predefined table schema to fulfill our requirement. Now we need to create the appropriate tables in the database, write some JDBC code to read information from the database, and make some configuration, and then Spring Security will do the rest of the work for us.

Create Maven project

So, first, we will create a simple Maven project. To create a project in Eclipse, click on the File menu, then choose New→Maven Project
Then choose the project location and click Next.
Spring Security with Database Authentication using JAVA configuration in Spring

Now enter Group Id and Artifact Id and select packaging type as war (Web Archive) as shown:
Spring Security with Database Authentication using JAVA configuration in Spring

Click Finish to create the project.

Although we've created a maven project for this tutorial, we will use some of the configuration files from our previous tutorial. You can download the source code here.

POM.XML

Update pom.xml with required dependencies:
Spring Framework version is 5.3.21 and Spring Security version is 5.6.6 for this application. We have added Spring MVC, Servlet, JSPSecurity, and MySQL connector for JAVA and DBCP2 connection pool-related dependencies in pom.xml. We are using war as the packaging type, which is why we use the maven-war-plugin to build the application.

Database Tables

As we've discussed earlier, we need to create some database tables. Below is the SQL script snippet to set up tables:

PasswordEncoder

In the previous section, we've used the phrase {noop} in the password column value in the users table - in Spring 5.0 and onward if we want to store passwords in the database table, we've to store them in encoded format. So the format for a password is - {id}encodedPassword - here id is the identifier for the PasswordEncoder.

One of the PasswordEncoder is NoOpPasswordEncoder which is used when we want to store plain text as our password and its id value is noop.

Here are some PasswordEncoders with their id values:
  • id value of NoOpPasswordEncoder is noop
  • id value of BCryptPasswordEncoder is bcrypt
  • id value of SCryptPasswordEncoder is scrypt
  • id value of Pbkdf2PasswordEncoder is pbkdf2
  • id value of StandardPasswordEncoder is sha256
As we're going to store passwords as plain text, that is why we've used {noop} with our password string. So, when Spring gets password value with {noop} phrase, it'll understand that the password is in plain text.

Connect to Database

In the app-db.properties file under the resource directory, we've configured Jdbc connection properties to connect MySQL database, secure_spring_mvc_db_auth:

Application Configuration

From the previous tutorial, we've copied the ApplicationConfiguration class in the config package and this class will act as Spring configuration. Here we're going to define our data source:
Here, we've mapped our app-db.properties file using @PropertySource annotation. So this property file will be automatically copied to classpath during Maven build. We've autowired the Environment class, a Spring Helper class - with it, we can access the property values in the application.

We've also defined a bean using @Bean annotation to configure our datasource using the property values.

This class also contains the configuration of ViewResolver using Java configuration, which is required for Spring Web MVC applications. We are using JSP as our view technology.

Initialize Dispatcher Servlet

The dispatcher servlet is responsible for forwarding/dispatching the request to the appropriate controller method. To initialize our Spring WebMVC application in the Servlet container environment using JAVA configuration, we create the ApplicationDispatherServletInitializer class in the config package which will extend the AbstractAnnotationConfigDispatcherServletInitializer class.

Initialize Application Security

Now, we need to create a security initializer class that will extend AbstractSecurityWebApplicationInitializer. Here is our ApplicationSecurityInitializer class which will reside config package:
AbstractSecurityWebApplicationInitializer helps us to register the DelegatingFilterProxy to use the Spring Security Filter.

Configure Application Security

As we are going to customize the security configuration, we will disable auto security configuration and specify the user name and its password - that is why we need to create a custom security configuration class by extending the WebSecurityConfigurerAdapter class. So, create the ApplicationSecutiryConfiguration class in the config package:
So, first of all, we've injected our jdbcDataSource here, and then in the configure(AuthenticationManagerBuilder auth), we are telling AuthenticationManagerBuilder that we'll use JDBC Authentication and assign our datasource to it. We've also configured HttpSecurity for our custom login page and logout functionality.

Controller

Create a HomeController class in the controller package:
Our showHome() method will return home, and based on our configuration, the view resolver will look for home.jsp (as we are using JSP as our view technology) in /WEB-INF/view/. So we need to create home.jsp in /WEB-INF/view/.

Now create the CustomLoginController class controller package. Here it is:
Our showCustomLoginPage() method will return customLoginForm, and based on our configuration, view resolver will search for customLoginForm.jsp in /WEB-INF/view/. So we need to create customLoginForm.jsp in /WEB-INF/view/.

View Page

To create the view page, first, create a view directory under /WEB-INF. Then create a home.jsp in the view directory:
So this page is the same as our previous tutorial with logout functionality.

Now create a customLoginForm.jsp in the view directory in /WEB-INF/:
OK, this is our custom login page. We've used the Bootstrap framework and some custom CSS to design this page. Along with these we've also used the Spring MVC form tag to POST user credentials. We've mapped /authenticateTheUser with the action value of the form tag - so that the Spring framework will do the rest of the job for us.

Test the Application

Now run this application and put this URL - http://localhost:8080/secure-spring-mvc-db-auth/, in the browser:
Spring Security with JDBC Authentication using JAVA configuration

Now enter admin as username and admin123 as password as we had stored in the database and press LOG IN to submit the page and the request will be redirected to the home page:
Spring Security with JDBC Authentication using JAVA configuration
Here, on the home page, we can see the logout button and you can press the logout button to check the logout functionality.
Spring Security with JDBC Authentication using JAVA configuration

As we've logged out from the application, a logout status message is given to the user.

So in this tutorial, we set up Spring Security recommended DB tables, configure the JDBC data source, and use that data source to authenticate the user.

You can download the source code from here.
Happy coding!!! 😊
in

References


No comments:

Post a Comment

Popular posts