From 13b769cd370c372a9e125ab268ec86e58b035f6f Mon Sep 17 00:00:00 2001 From: Abhinav Pandey Date: Sun, 13 Feb 2022 14:31:17 +0530 Subject: [PATCH] BAEL-5340 - Spring security configuring ant matchers --- .../AntMatchersExampleApplication.java | 13 +++++++ .../config/SecurityConfiguration.java | 39 +++++++++++++++++++ .../controllers/CustomerController.java | 15 +++++++ .../controllers/ProductController.java | 21 ++++++++++ .../baeldung/antmatchers/dtos/Customer.java | 39 +++++++++++++++++++ .../baeldung/antmatchers/dtos/Product.java | 39 +++++++++++++++++++ .../controllers/CustomerControllerTest.java | 38 ++++++++++++++++++ .../controllers/ProductControllerTest.java | 25 ++++++++++++ 8 files changed, 229 insertions(+) create mode 100644 spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/AntMatchersExampleApplication.java create mode 100644 spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/config/SecurityConfiguration.java create mode 100644 spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/controllers/CustomerController.java create mode 100644 spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/controllers/ProductController.java create mode 100644 spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/dtos/Customer.java create mode 100644 spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/dtos/Product.java create mode 100644 spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/antmatchers/controllers/CustomerControllerTest.java create mode 100644 spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/antmatchers/controllers/ProductControllerTest.java diff --git a/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/AntMatchersExampleApplication.java b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/AntMatchersExampleApplication.java new file mode 100644 index 0000000000..0a7828eff4 --- /dev/null +++ b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/AntMatchersExampleApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.antmatchers; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AntMatchersExampleApplication { + + public static void main(String[] args) { + SpringApplication.run(AntMatchersExampleApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/config/SecurityConfiguration.java b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/config/SecurityConfiguration.java new file mode 100644 index 0000000000..43e8c73bf0 --- /dev/null +++ b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/config/SecurityConfiguration.java @@ -0,0 +1,39 @@ +package com.baeldung.antmatchers.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class SecurityConfiguration extends WebSecurityConfigurerAdapter { + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("admin").password(passwordEncoder().encode("password")).roles("USER", "ADMIN") + .and() + .withUser("user").password(passwordEncoder().encode("password")).roles("USER"); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/products/**").permitAll() + .and() + .authorizeRequests() + .antMatchers("/customers/**").hasRole("ADMIN") + .anyRequest().authenticated() + .and() + .httpBasic(); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/controllers/CustomerController.java b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/controllers/CustomerController.java new file mode 100644 index 0000000000..a031449797 --- /dev/null +++ b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/controllers/CustomerController.java @@ -0,0 +1,15 @@ +package com.baeldung.antmatchers.controllers; + +import com.baeldung.antmatchers.dtos.Customer; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class CustomerController { + + @GetMapping("/customers/{id}") + public Customer getCustomerById(@PathVariable("id") String id) { + return new Customer("Customer 1", "Address 1", "Phone 1"); + } +} diff --git a/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/controllers/ProductController.java b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/controllers/ProductController.java new file mode 100644 index 0000000000..2968f3c025 --- /dev/null +++ b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/controllers/ProductController.java @@ -0,0 +1,21 @@ +package com.baeldung.antmatchers.controllers; + +import com.baeldung.antmatchers.dtos.Product; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@RestController +public class ProductController { + + @GetMapping("/products") + public List getProducts() { + return new ArrayList<>(Arrays.asList( + new Product("Product 1", "Description 1", 1.0), + new Product("Product 2", "Description 2", 2.0) + )); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/dtos/Customer.java b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/dtos/Customer.java new file mode 100644 index 0000000000..64bd95b095 --- /dev/null +++ b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/dtos/Customer.java @@ -0,0 +1,39 @@ +package com.baeldung.antmatchers.dtos; + +import java.io.Serializable; + +public class Customer implements Serializable { + private String name; + private String address; + private String phone; + + public Customer(String name, String address, String phone) { + this.name = name; + this.address = address; + this.phone = phone; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } +} diff --git a/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/dtos/Product.java b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/dtos/Product.java new file mode 100644 index 0000000000..84073ee8c0 --- /dev/null +++ b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/antmatchers/dtos/Product.java @@ -0,0 +1,39 @@ +package com.baeldung.antmatchers.dtos; + +import java.io.Serializable; + +public class Product implements Serializable { + private String name; + private String description; + private double price; + + public Product(String name, String description, double price) { + this.name = name; + this.description = description; + this.price = price; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/antmatchers/controllers/CustomerControllerTest.java b/spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/antmatchers/controllers/CustomerControllerTest.java new file mode 100644 index 0000000000..de13dc0aea --- /dev/null +++ b/spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/antmatchers/controllers/CustomerControllerTest.java @@ -0,0 +1,38 @@ +package com.baeldung.antmatchers.controllers; + +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@WebMvcTest(value = CustomerController.class) +class CustomerControllerIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void getCustomerByIdUnauthorized() throws Exception { + mockMvc.perform(get("/customers/1")).andExpect(status().isUnauthorized()); + } + + @Test + void getCustomerByIdForbidden() throws Exception { + mockMvc.perform(get("/customers/1").with(user("user").roles("USER"))) + .andExpect(status().isForbidden()); + } + + @Test + void getCustomerByIdOk() throws Exception { + mockMvc.perform(get("/customers/1").with(user("admin").roles("ADMIN"))) + .andExpect(status().isOk()); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/antmatchers/controllers/ProductControllerTest.java b/spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/antmatchers/controllers/ProductControllerTest.java new file mode 100644 index 0000000000..370e5f1597 --- /dev/null +++ b/spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/antmatchers/controllers/ProductControllerTest.java @@ -0,0 +1,25 @@ +package com.baeldung.antmatchers.controllers; + +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@WebMvcTest(value = ProductController.class) +class ProductControllerIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void getProducts() throws Exception { + mockMvc.perform(get("/products")) + .andExpect(status().isOk()); + } +} \ No newline at end of file