Skip to content

Commit cf98b08

Browse files
committed
feat(springSecurity): add spring security in app
1 parent 65800bf commit cf98b08

7 files changed

Lines changed: 80 additions & 12 deletions

File tree

.env.template

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ POSTGRES_PASSWORD=your_postgres_password
33
POSTGRES_DB=your_postgres_db
44
POSTGRES_PORT=5432
55

6+
# Spring Security
7+
APP_SECURITY_USER=your_api_username
8+
APP_SECURITY_PASSWORD=your_api_password
9+
610
# Liquibase configuration
711
LB_CHANGELOG=your_changelog_file.yaml
812
LB_OUTPUT_CHANGELOG=your_output_changelog.yaml

pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@
6969
<groupId>org.springframework.boot</groupId>
7070
<artifactId>spring-boot-starter-webmvc</artifactId>
7171
</dependency>
72+
<dependency>
73+
<groupId>org.springframework.boot</groupId>
74+
<artifactId>spring-boot-starter-security</artifactId>
75+
</dependency>
7276
<dependency>
7377
<groupId>org.springdoc</groupId>
7478
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.xpeho.spring_boot_java_random_user.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.http.HttpMethod;
6+
import org.springframework.security.config.Customizer;
7+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
8+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
9+
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
10+
import org.springframework.security.config.http.SessionCreationPolicy;
11+
import org.springframework.security.web.SecurityFilterChain;
12+
13+
@Configuration
14+
@EnableWebSecurity
15+
public class SecurityConfig {
16+
17+
@Bean
18+
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
19+
http
20+
.csrf(AbstractHttpConfigurer::disable)
21+
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
22+
.httpBasic(Customizer.withDefaults())
23+
.authorizeHttpRequests(auth -> auth
24+
.requestMatchers(
25+
"/api/**",
26+
"/swagger-ui/**",
27+
"/swagger-ui.html",
28+
"/v3/api-docs/**",
29+
"/actuator/health"
30+
).permitAll()
31+
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
32+
.anyRequest().authenticated()
33+
);
34+
35+
return http.build();
36+
}
37+
}

src/main/resources/application.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
spring.application.name=spring_boot_java_random_user
22

3+
# Security
4+
spring.security.user.name=${APP_SECURITY_USER}
5+
spring.security.user.password=${APP_SECURITY_PASSWORD}
6+
spring.security.user.roles=USER
7+
38
# Swagger UI custom path
49
springdoc.swagger-ui.path=/api
510

src/test/java/com/xpeho/spring_boot_java_random_user/presentation/UserGetByIdContainerTest.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,17 @@
2626
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
2727
properties = {
2828
"spring.sql.init.mode=never",
29-
"spring.jpa.hibernate.ddl-auto=create-drop"
29+
"spring.jpa.hibernate.ddl-auto=create-drop",
30+
"spring.security.user.name=testuser",
31+
"spring.security.user.password=testpass",
32+
"spring.security.user.roles=USER"
3033
}
3134
)
3235
class UserGetByIdContainerTest {
3336

37+
private static final String TEST_USERNAME = "testuser";
38+
private static final String TEST_PASSWORD = "testpass";
39+
3440
@Container
3541
@ServiceConnection
3642
static PostgreSQLContainer postgres = new PostgreSQLContainer("postgres:17-alpine");
@@ -61,8 +67,8 @@ void shouldReturnUserByIdWhenUserExists() {
6167

6268
User saved = userRepository.saveAndFlush(user);
6369

64-
ResponseEntity<UserEntity> response = restTemplate.getForEntity(
65-
"/random-users/{id}",
70+
ResponseEntity<UserEntity> response = restTemplate.withBasicAuth(TEST_USERNAME, TEST_PASSWORD).getForEntity(
71+
"/random-users/{id}",
6672
UserEntity.class,
6773
saved.getId()
6874
);
@@ -77,10 +83,10 @@ void shouldReturnUserByIdWhenUserExists() {
7783
@Test
7884
@DisplayName("GET /random-users/{id} should return 404 when user does not exist")
7985
void shouldReturnNotFoundWhenUserDoesNotExist() {
80-
ResponseEntity<UserEntity> response = restTemplate.getForEntity(
81-
"/random-users/{id}",
86+
ResponseEntity<UserEntity> response = restTemplate.withBasicAuth(TEST_USERNAME, TEST_PASSWORD).getForEntity(
87+
"/random-users/{id}",
8288
UserEntity.class,
83-
-1
89+
-1
8490
);
8591

8692
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);

src/test/java/feature/SpringIntegrationTest.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
)
2828
public class SpringIntegrationTest {
2929

30+
private static final String TEST_USERNAME = "testuser";
31+
private static final String TEST_PASSWORD = "testpass";
32+
3033
@Autowired
3134
protected TestRestTemplate restTemplate;
3235

@@ -37,19 +40,25 @@ public class SpringIntegrationTest {
3740

3841
protected void executeGet(String path) {
3942
String url = "http://localhost:" + port + path;
40-
latestResponse = restTemplate.getForEntity(url, String.class);
43+
latestResponse = restTemplate
44+
.withBasicAuth(TEST_USERNAME, TEST_PASSWORD)
45+
.getForEntity(url, String.class);
4146
}
4247

4348
protected void executePost(String path, Object payload) {
4449
String url = "http://localhost:" + port + path;
4550
HttpHeaders headers = new HttpHeaders();
4651
headers.setContentType(MediaType.APPLICATION_JSON);
4752
HttpEntity<Object> request = new HttpEntity<>(payload, headers);
48-
latestResponse = restTemplate.postForEntity(url, request, String.class);
53+
latestResponse = restTemplate
54+
.withBasicAuth(TEST_USERNAME, TEST_PASSWORD)
55+
.postForEntity(url, request, String.class);
4956
}
5057

5158
protected void executeDelete(String path) {
5259
String url = "http://localhost:" + port + path;
53-
latestResponse = restTemplate.exchange(url, HttpMethod.DELETE, HttpEntity.EMPTY, String.class);
60+
latestResponse = restTemplate
61+
.withBasicAuth(TEST_USERNAME, TEST_PASSWORD)
62+
.exchange(url, HttpMethod.DELETE, HttpEntity.EMPTY, String.class);
5463
}
5564
}
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
spring.datasource.url=${H2_URL};MODE=PostgreSQL;DATABASE_TO_UPPER=false;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
1+
spring.datasource.url=${H2_URL:jdbc:h2:mem:mydb};MODE=PostgreSQL;DATABASE_TO_UPPER=false;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
22
spring.datasource.driver-class-name=org.h2.Driver
3-
spring.datasource.username=${H2_USERNAME}
4-
spring.datasource.password=${H2_PASSWORD}
3+
spring.datasource.username=${H2_USERNAME:myusername}
4+
spring.datasource.password=${H2_PASSWORD:mypassword}
5+
spring.security.user.name=testuser
6+
spring.security.user.password=testpass
7+
spring.security.user.roles=USER
58
spring.sql.init.mode=never
69
spring.docker.compose.enabled=false

0 commit comments

Comments
 (0)