SSL in JPA App

This commit is contained in:
Saikat Chakraborty 2022-09-20 21:50:05 +05:30
parent 82dfba062c
commit 98bc9c336b
8 changed files with 252 additions and 6 deletions

View File

@ -0,0 +1,2 @@
CREATE USER 'test_user'@'%' IDENTIFIED BY 'Password2022' require X509;
GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'%';

View File

@ -0,0 +1,24 @@
version: '3.8'
services:
mysql-service:
image: "mysql/mysql-server:8.0.30"
container_name: mysql-db
command: [ "mysqld",
"--require_secure_transport=ON",
"--ssl-ca=/etc/certs/root-ca.pem",
"--ssl-cert=/etc/certs/server-cert.pem",
"--ssl-key=/etc/certs/server-key.pem",
"--default_authentication_plugin=mysql_native_password",
"--general_log=ON" ]
ports:
- "3306:3306"
volumes:
- type: bind
source: ./certs
target: /etc/certs/
restart: always
environment:
MYSQL_ROOT_HOST: "%"
MYSQL_ROOT_PASSWORD: "Password2022"
MYSQL_DATABASE: test_db

View File

@ -0,0 +1,35 @@
mkdir certs
cd ./certs
# Generate new CA certificate ca.pem file.
openssl genrsa 2048 > root-ca-key.pem
openssl req -new -x509 -nodes -days 3600 \
-subj "/C=SE/ST=STOCKHOLM/L=Test/CN=fake-CA" \
-key root-ca-key.pem -out root-ca.pem
# Create the server-side certificates
openssl req -newkey rsa:2048 -days 3600 -nodes \
-subj "/C=SE/ST=STOCKHOLM/L=Test/CN=localhost" \
-keyout server-key.pem -out server-req.pem
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 3600 \
-CA root-ca.pem -CAkey root-ca-key.pem -set_serial 01 -out server-cert.pem
# Create the client-side certificates
openssl req -newkey rsa:2048 -days 3600 -nodes \
-subj "/C=SE/ST=STOCKHOLM/L=Test/CN=localhost" \
-keyout client-key.pem -out client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 3600 \
-CA root-ca.pem -CAkey root-ca-key.pem -set_serial 01 -out client-cert.pem
# Verify the certificates are correct
openssl verify -CAfile root-ca.pem server-cert.pem client-cert.pem
# Convert pem to jks file
keytool -importcert -alias MySQLCACert.jks -file root-ca.pem \
-keystore truststore.jks -storepass mypassword
openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -out certificate.p12 -name "certificate"
keytool -importkeystore -srckeystore certificate.p12 -srcstoretype pkcs12 -destkeystore cert.jks

View File

@ -0,0 +1,59 @@
package com.baeldung.boot.jpa;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Date;
@Entity
public class Employee implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Integer id;
@Column(name = "emp_name")
private String empName;
@Column(name = "job_title")
private String jobTitle;
@Column(name = "emp_doj")
private LocalDate empDoj;
@Column(name = "created_date")
private Date createdDate = new Date();
public Integer getId() {
return id;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getJobTitle() {
return jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
public LocalDate getEmpDoj() {
return empDoj;
}
public void setEmpDoj(LocalDate empDoj) {
this.empDoj = empDoj;
}
public Date getCreatedDate() {
return createdDate;
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.boot.jpa;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
public class EmployeeController {
@Autowired
private EmployeeRepository empRepository;
@GetMapping("/employee/{empId}")
public Employee get(@PathVariable(name = "empId") Integer empId) {
return empRepository.findById(empId).get();
}
@PostMapping("/employee")
public Employee createUser(@RequestBody Employee employee) {
System.out.println(employee);
empRepository.save(employee);
return employee;
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.boot.jpa;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Serializable> {
}

View File

@ -1,9 +1,8 @@
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?
username: root
password:
profiles:
active: "dev2"
main:
banner-mode: "off"
jpa:
hibernate:
ddl-auto: update
@ -11,4 +10,26 @@ spring:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
jdbc:
time_zone: UTC
time_zone: UTC
---
spring:
profiles: "dev1"
datasource:
url: jdbc:mysql://localhost:3306/test?
username: root
password:
---
spring:
profiles: "dev2"
datasource:
url: >-
jdbc:mysql://localhost:3306/test_db?sslMode=VERIFY_IDENTITY&
trustCertificateKeyStoreUrl=file:/Users/saikatchakraborty/tutorials/persistence-modules/spring-boot-mysql/mysql-server/certs/truststore.jks&
trustCertificateKeyStorePassword=mypassword&
clientCertificateKeyStoreUrl=file:/Users/saikatchakraborty/tutorials/persistence-modules/spring-boot-mysql/mysql-server/certs/cert.jks&
clientCertificateKeyStorePassword=mypassword
username: test_user
password: Password2022

View File

@ -0,0 +1,72 @@
package com.baeldung.boot.jpa;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import java.time.LocalDate;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@WebMvcTest(EmployeeController.class)
public class EmployeeControllerUnitTest {
@MockBean
private EmployeeRepository employeeRepository;
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Test
public void givenEmployeeId_whenGetEmployeeCalled_ThenReturnEmployee() throws Exception {
Employee employeeExpected = new Employee();
employeeExpected.setEmpName("Test Emp");
employeeExpected.setEmpDoj(LocalDate.now());
employeeExpected.setJobTitle("Manager");
Mockito.when(employeeRepository.findById(1234)).thenReturn(Optional.of(employeeExpected));
MvcResult result = mockMvc.perform(get("/employee/1234"))
.andExpect(status().isOk()).andReturn();
Employee employee = objectMapper.readValue(result.getResponse().getContentAsString(), Employee.class);
assertEquals(employeeExpected.getEmpName(), employee.getEmpName());
assertEquals(employeeExpected.getJobTitle(), employee.getJobTitle());
assertEquals(employeeExpected.getEmpDoj(), employee.getEmpDoj());
}
@Test
public void givenEmployee_whenCreateEmployeeCalled_ThenReturnEmployee() throws Exception {
Employee employeeExpected = new Employee();
employeeExpected.setEmpName("Test Emp");
employeeExpected.setEmpDoj(LocalDate.now());
employeeExpected.setJobTitle("Manager");
Mockito.when(employeeRepository.save(employeeExpected)).thenReturn(employeeExpected);
MvcResult result = mockMvc.perform(post("/employee")
.content(objectMapper.writeValueAsString(employeeExpected))
.contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andReturn();
Employee employee = objectMapper.readValue(result.getResponse().getContentAsString(), Employee.class);
assertEquals(employeeExpected.getEmpName(), employee.getEmpName());
assertEquals(employeeExpected.getJobTitle(), employee.getJobTitle());
assertEquals(employeeExpected.getEmpDoj(), employee.getEmpDoj());
}
}