Spring Boot Security

Spring Boot Security with Examples

In this article, I am going to discuss Spring Boot Security with Examples. Please read our previous article where we discussed Spring Boot HTTP Header Versioning with Examples.

What is Spring Security?

We have learned how to create several REST APIs so far. None of these APIs are secure as no authentication is performed before the data is sent to the client. In this exercise, we will implement basic authentication.

Spring Boot offers multiple authentication methods. The most convenient method is basic authentication. With this method, the client sends a username and password as part of the request. If the username and password combination is correct, the client is granted access to the data.

There are also more advanced forms of authentication, such as digest authentication, where a password digest is created and sent instead of the actual password. Another advanced form of authentication is OAuth (Open Authorization) or OAuth2 authentication.

Implementing Authentication in Spring Boot

Let’s now learn how to implement basic authentication in web services. For this project, we shall again use the fruits API. The project should have the following class files:

  • Fruits.java
  • FruitServiceController.java
  • SecurityApplication.java

The contents of these files need not be modified in this project. The code in these files is provided at the end of this webpage.

As of now, the application does not have any form of authentication. We will have to implement this using Spring Security.

Step 1: Add the Spring Security dependency to the project using the “Add Starters…” option. This option is available in the right-click menu of the pom.xml file.

Implementing Authentication in Spring Boot

Ensure that the dependency has been installed:

Implementing Authentication in Spring Boot

Step 2: Compile and execute the application. Ensure compilation is successful.

What is Spring Security?

As can be seen from the terminal output, a password is generated for authentication. Note that this password shall change every time the application is restarted.

Step 3: Send a GET request to the URL http://localhost:8080/products via Postman. You should see the following error:

What is Spring Security?

This error occurs because we have not entered a user id and password.

Step 4: Send a GET request to the URL http://localhost:8080/products via Postman. Remember to enter the userid and password using the authorization tab in Postman. Copy the password correctly from the Spring Boot terminal window. You should see the following reply:

Spring Boot Security with Examples

As can be seen, this returns the expected output. If we enter the incorrect password, the following error will be displayed:

Spring Boot Security with Examples

Step 5: Until now, we have been using the password automatically created by Spring Boot. A better option would be to configure the user id and password ourselves. This can be done by modifying the application.properties file.

Spring Boot Security

Step 6: Compile and execute the application. Ensure compilation is successful.

Spring Boot Security

As can be seen from the terminal output, Spring Boot does not generate a new password for us to use.

Step 7: Send a GET request to the URL http://localhost:8080/products via Postman. Remember to enter the userid and password using the authorization tab in Postman. Enter the password as you have done in the application.properties file.

Spring Boot Security Examples

Congratulations! You now know how to implement authorization in Spring Boot. Note that this is just basic authentication, which can be breached easily. Other forms of authentication, such as OAuth and OAuth2 provide a much more secure authorization mechanism.

The Complete Example Code
Fruits.java
package com.dotnet.security;

public class Fruits {
    private String id;
    private String name;
 
    public String getId()               {return id;}
    public void setId(String id)        {this.id = id;}
    public String getName()             {return name;}
    public void setName(String name)    {this.name = name;}

    public Fruits (String nid, String nname)
    {
        id = nid;
        name = nname;
    }
 }
FruitServiceController.java
package com.dotnet.security;

//Map classes
import java.util.HashMap;
import java.util.Map;

//Required web classes
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FruitServiceController {
   private static Map<String, Fruits> productRepo = new HashMap<>();
   static {
      Fruits apple = new Fruits("1","Apple");
      productRepo.put(apple.getId(), apple);

      Fruits banana = new Fruits("2","Banana");
      productRepo.put(banana.getId(), banana);

      Fruits chiku = new Fruits("3","Chiku");
      productRepo.put(chiku.getId(), chiku);

      Fruits dragon = new Fruits("4","Dragon Fruit");
      productRepo.put(dragon.getId(), dragon);
   }
   
   @RequestMapping(value = "/products/{id}", method = RequestMethod.DELETE)
   public ResponseEntity<Object> delete(@PathVariable("id") String id)
   {
      productRepo.remove(id);
      return new ResponseEntity<>("Fruit is deleted!", HttpStatus.OK);
   }
   
   @RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
   public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Fruits product)
   { 
      productRepo.remove(id);
      product.setId(id);
      productRepo.put(id, product);
      return new ResponseEntity<>("Fruit is updated!", HttpStatus.OK);
   }
   
   @RequestMapping(value = "/products", method = RequestMethod.POST)
   public ResponseEntity<Object> createProduct(@RequestBody Fruits product) {
      productRepo.put(product.getId(), product);
      return new ResponseEntity<>("Fruit is created!", HttpStatus.CREATED);
   }
   
   @RequestMapping(value = "/products")
   public ResponseEntity<Object> getProduct() {
      return new ResponseEntity<>(productRepo.values(), HttpStatus.OK);
   }
}
SecurityApplication.java
package com.dotnet.security;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SecurityApplication {

 public static void main(String[] args) {
  SpringApplication.run(SecurityApplication.class, args);
 }
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>3.1.0</version>
  <relativePath/> <!-- lookup parent from repository -->
 </parent>
 <groupId>com.dotnet</groupId>
 <artifactId>security</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>security</name>
 <description>Demo project for Spring Boot</description>
 <properties>
  <java.version>17</java.version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter</artifactId>
  </dependency>

  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
  </dependency>

  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
  </dependency>
 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>

</project>
application.properties
spring.security.user.name=user  
spring.security.user.password=secure_pass

In the next article, I am going to discuss Richardson Maturity Model with Examples. Here, in this article, I try to explain Spring Boot Security with Examples. I hope you enjoy this Spring Boot Security article.

Leave a Reply

Your email address will not be published. Required fields are marked *