IMPLEMENTING SECURITY IN SPRING

Nikhil Bhatnagar
5 min readAug 21, 2020

During the creation of a web application, a developer needs to authenticate the user to use the application. This can be done by a simple log-in, log-out authentication, or by OAuth2 or any other way. So for the aid of a developer, Spring has such features in-built.

1. Create a simple web starter project.

2. Now for demo purposes, we need some data. So, we create a controller class called HomeController. This controller will we returning a webpage and this very webpage will be secured by us via authentication purposes.

Controller returning a web page

3. Inside src>main, create a new folder to create the webpage “HomePage.html”. Right-click on this folder and create a new file of type HTML and write a text inside this file which will be displayed on the call of the above controller.

4. Run the application and the “HomePage.html” page will be displayed.

Now suppose, we want to give authenticate the user viewing this page. This can be done simply via a login process, where the user will enter his details inside a login form. Spring by default gives us the option of login and logout. To implement this,

1. Go to the MVN repository page.

2. Search for “Spring Boot Starter Security”. Click on any version of your choice. Copy the maven dependencies and paste it inside the pom.xml file.

The link for the same is:-

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security

3. Now, restart the server and go to localhost:8080. You’ll find a well-developed login page automatically built, the user name of which is by default “user” and the password for the same is generated in the console.

Being a developer, we always need to set our own password, username, etc etc. As such we need to do configurations in the implicitly provided application. To do so:-

A. Create a new class where we can have all the configurations.

B. Extend that class with WebSecurityConfigurerAdapter. This has all the in-built methods we need for configuration.

C. Annotate the class with @Configuration and @EnableWebSecurity. These are the standard annotations used for enabling configuration in web-based applications.

D. Now, we need to override the methods of WebSecurityConfigurerAdapter class. As such, right-click in the empty body of the class. Click on source>override methods> UserDetailsService.

E. A new method will be generated with @override annotation on it. Further, as we need to add an instance of the class UserDetailsService, we add the annotation @Bean over the class name.

F. The created overridden method will handle our user details. Details of a user, in spring, is handled by a class called UserDetails.

G. This class has methods to store and use the credentials of a user. The following code facilitates the same.

Basic login authentication

· UserDetails class stores the details like password etc. As such, we need a POJO to store the details. As such, we use a List for the same purpose.

· Inside the add() method:-

We class a depreciated method, withDefaultPasswordEncoder(). It’s a method of User class which takes the details statically and build credential for a user.

Username(), password() takes in name and password for the login of the user.

roles() method is used to determine the role of the user, so that we can differentiate between an admin and a regular user.

· Lastly, the above details are static and not taken from the user. As such we use the in-built, user details manager, and return it from the method.

H. To test the above changes, just restart the server and we are good to go.

Dynamic creation of username and password

Static creation of passwords is of no use as in an application, we always want to retrieve user data from the database. As such, we need to make certain changes to our existing code.

1. Create a new method that returns an object of AuthenticationProvider. Annotate it with @Bean.

2. Inside the method, create an object of DaoAuthenticationProvider provider=new DaoAuthenticationProvider(). This is an in-built class that uses DAO and helps to communicate with the database and access the built-in methods.

3. Now, we’ll also need a database. As such, we import two dependencies namely, spring-jpa and mysql connector. The dependencies can be downloaded from mvn repository.

4. We also need to tell Spring about the database etc. As such, open src/main/resources>application.properties. Inside this file, we need to mention the localhost on which mysql server is working, followed by username, password, and the driver name.

5. Create a table in the MySQL database and to enter the data in the same, create a new class with the same fields and annotate it with @Entity and @Id to map that class in the database with a primary key.

6. Further, we also need to create a class to receive data from the user and a class to connect the received data to our entity class.

7. Now, inside our above method, we need to change the details of the user from default to the credentials received. As such, we call a method setUserDetailsService() via the above created “provider” object and pass an object of UserDetailsService as the parameter. Again, we’ll be setting the user details and as such, we need to encode the details. Hence we call the deprecated withDefaultPasswordEncoder() method. Inside the method we’ll call “NoOpPasswordEncoder.getInstance()” method. This is also deprecated as it stores the details locally which isn’t advisable but for demo purpose, we can use the same. Now, just return the provider object and we are good to go.

NOTE:- The object of UserDetailsService can’t be created normally as it’s an interface and not a class. As such, we need to create an additional class, implement this interface, and then use the object of that class. Also, to load the data from db, we can use the methods of UserDetailsService like loadDetails (), etc.

Now, we need to decrypt our user passwords, etc. The NoOpPasswordEncoder.getInstance()”, doesn’t encode the data but it simply stores it as a plain text. To remove this, we just need to create:-

new BcryptPasswordEncoder ()

and the user details will be encrypted automatically. We can authenticate the user login via social networking sites etc using OAuth2, etc.

Thanks for reading !!

--

--

Nikhil Bhatnagar

A tech enthusiast who loves to read and write about new technologies and trends. Software engineer @HashedinByDeloitte