Skip to content

Commit 2ee9762

Browse files
committed
Refactor security configuration for development and production profiles; update application properties for JWT validation and Azure settings
1 parent a5d0752 commit 2ee9762

7 files changed

Lines changed: 92 additions & 33 deletions

File tree

sample-app/api/applicationinsights.log

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,51 @@ No connection string provided
1010
Action:
1111
Please provide connection string: https://go.microsoft.com/fwlink/?linkid=2153358
1212

13+
2026-04-20 21:07:02.812-04:00 INFO c.m.a.a.i.c.ConfigurationBuilder - Some telemetry may be sampled out because a default sampling configuration was added in version 3.4.0 to reduce the default billing cost. You can set the sampling configuration explicitly: https://learn.microsoft.com/azure/azure-monitor/app/java-standalone-config#sampling
14+
2026-04-20 21:07:03.048-04:00 ERROR c.m.applicationinsights.agent -
15+
*************************
16+
Application Insights Java Agent 3.7.8 startup failed (PID 60188)
17+
*************************
18+
19+
Description:
20+
No connection string provided
21+
22+
Action:
23+
Please provide connection string: https://go.microsoft.com/fwlink/?linkid=2153358
24+
25+
2026-04-21 21:11:47.647-04:00 INFO c.m.a.a.i.c.ConfigurationBuilder - Some telemetry may be sampled out because a default sampling configuration was added in version 3.4.0 to reduce the default billing cost. You can set the sampling configuration explicitly: https://learn.microsoft.com/azure/azure-monitor/app/java-standalone-config#sampling
26+
2026-04-21 21:11:47.857-04:00 ERROR c.m.applicationinsights.agent -
27+
*************************
28+
Application Insights Java Agent 3.7.8 startup failed (PID 36416)
29+
*************************
30+
31+
Description:
32+
No connection string provided
33+
34+
Action:
35+
Please provide connection string: https://go.microsoft.com/fwlink/?linkid=2153358
36+
37+
2026-04-21 21:16:48.841-04:00 INFO c.m.a.a.i.c.ConfigurationBuilder - Some telemetry may be sampled out because a default sampling configuration was added in version 3.4.0 to reduce the default billing cost. You can set the sampling configuration explicitly: https://learn.microsoft.com/azure/azure-monitor/app/java-standalone-config#sampling
38+
2026-04-21 21:16:49.076-04:00 ERROR c.m.applicationinsights.agent -
39+
*************************
40+
Application Insights Java Agent 3.7.8 startup failed (PID 77224)
41+
*************************
42+
43+
Description:
44+
No connection string provided
45+
46+
Action:
47+
Please provide connection string: https://go.microsoft.com/fwlink/?linkid=2153358
48+
49+
2026-04-21 21:18:40.872-04:00 INFO c.m.a.a.i.c.ConfigurationBuilder - Some telemetry may be sampled out because a default sampling configuration was added in version 3.4.0 to reduce the default billing cost. You can set the sampling configuration explicitly: https://learn.microsoft.com/azure/azure-monitor/app/java-standalone-config#sampling
50+
2026-04-21 21:18:41.088-04:00 ERROR c.m.applicationinsights.agent -
51+
*************************
52+
Application Insights Java Agent 3.7.8 startup failed (PID 18328)
53+
*************************
54+
55+
Description:
56+
No connection string provided
57+
58+
Action:
59+
Please provide connection string: https://go.microsoft.com/fwlink/?linkid=2153358
60+

sample-app/api/pom.xml

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,8 @@
1919

2020
<properties>
2121
<java.version>17</java.version>
22-
<spring-cloud-azure.version>7.2.0</spring-cloud-azure.version>
2322
</properties>
2423

25-
<dependencyManagement>
26-
<dependencies>
27-
<dependency>
28-
<groupId>com.azure.spring</groupId>
29-
<artifactId>spring-cloud-azure-dependencies</artifactId>
30-
<version>${spring-cloud-azure.version}</version>
31-
<type>pom</type>
32-
<scope>import</scope>
33-
</dependency>
34-
</dependencies>
35-
</dependencyManagement>
36-
3724
<dependencies>
3825
<!-- Spring Boot -->
3926
<dependency>
@@ -45,12 +32,6 @@
4532
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
4633
</dependency>
4734

48-
<!-- Spring Cloud Azure AD -->
49-
<dependency>
50-
<groupId>com.azure.spring</groupId>
51-
<artifactId>spring-cloud-azure-starter-active-directory</artifactId>
52-
</dependency>
53-
5435
<!-- Azure Storage -->
5536
<dependency>
5637
<groupId>com.azure</groupId>

sample-app/api/src/main/java/com/example/evidence/config/SecurityConfig.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.springframework.beans.factory.annotation.Value;
44
import org.springframework.context.annotation.Bean;
55
import org.springframework.context.annotation.Configuration;
6+
import org.springframework.context.annotation.Profile;
67
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
78
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
89
import org.springframework.security.core.GrantedAuthority;
@@ -26,7 +27,25 @@ public class SecurityConfig {
2627
@Value("${app.cors.allowed-origins:http://localhost:4200}")
2728
private String allowedOrigins;
2829

30+
/**
31+
* Dev profile: permit all requests so the API is explorable before Entra ID
32+
* app registrations are configured. Participants enable real auth in Exercise 1.
33+
*/
2934
@Bean
35+
@Profile("dev")
36+
public SecurityFilterChain devFilterChain(HttpSecurity http) throws Exception {
37+
http
38+
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
39+
.csrf(csrf -> csrf.disable())
40+
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll());
41+
return http.build();
42+
}
43+
44+
/**
45+
* Non-dev profiles: full JWT validation with scope and role enforcement.
46+
*/
47+
@Bean
48+
@Profile("!dev")
3049
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
3150
http
3251
.cors(cors -> cors.configurationSource(corsConfigurationSource()))

sample-app/api/src/main/java/com/example/evidence/controller/CaseController.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.example.evidence.service.CaseService;
77
import org.springframework.http.ResponseEntity;
88
import org.springframework.security.access.prepost.PreAuthorize;
9+
import org.springframework.security.core.Authentication;
910
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
1011
import org.springframework.web.bind.annotation.GetMapping;
1112
import org.springframework.web.bind.annotation.PathVariable;
@@ -14,6 +15,7 @@
1415
import org.springframework.web.bind.annotation.RequestMapping;
1516
import org.springframework.web.bind.annotation.RestController;
1617

18+
import java.util.Collections;
1719
import java.util.HashMap;
1820
import java.util.List;
1921
import java.util.Map;
@@ -69,12 +71,19 @@ public ResponseEntity<CaseDetailResponse> createCase(@RequestBody Case newCase)
6971
}
7072

7173
@GetMapping("/me")
72-
public Map<String, Object> getCurrentUser(JwtAuthenticationToken authentication) {
74+
public Map<String, Object> getCurrentUser(Authentication authentication) {
7375
Map<String, Object> userInfo = new HashMap<>();
74-
userInfo.put("name", authentication.getToken().getClaimAsString("name"));
75-
userInfo.put("preferred_username", authentication.getToken().getClaimAsString("preferred_username"));
76-
userInfo.put("roles", authentication.getToken().getClaimAsStringList("roles"));
77-
userInfo.put("scp", authentication.getToken().getClaimAsString("scp"));
76+
if (authentication instanceof JwtAuthenticationToken jwtAuth) {
77+
userInfo.put("name", jwtAuth.getToken().getClaimAsString("name"));
78+
userInfo.put("preferred_username", jwtAuth.getToken().getClaimAsString("preferred_username"));
79+
userInfo.put("roles", jwtAuth.getToken().getClaimAsStringList("roles"));
80+
userInfo.put("scp", jwtAuth.getToken().getClaimAsString("scp"));
81+
} else {
82+
userInfo.put("name", "Dev User (no JWT)");
83+
userInfo.put("preferred_username", "dev@localhost");
84+
userInfo.put("roles", Collections.emptyList());
85+
userInfo.put("scp", "Evidence.Read");
86+
}
7887
return userInfo;
7988
}
8089
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
# Dev profile - local development with sample data
22
logging.level.com.example.evidence=DEBUG
33
logging.level.org.springframework.security=DEBUG
4+
5+
# No JWT validation in dev — API is open for exploration before Exercise 1
6+
# Participants configure real Entra ID auth during Exercise 1
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
# Prod profile - Azure Blob Storage
1+
# Prod profile - Azure deployment
22
azure.storage.account-name=${AZURE_STORAGE_ACCOUNT_NAME:YOUR_STORAGE_ACCOUNT}
33
azure.storage.container-name=${AZURE_STORAGE_CONTAINER_NAME:evidence}
4+
5+
# JWT validation against Entra ID tenant
6+
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0
Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
# Server
22
server.port=8080
33

4-
# Azure AD / Entra ID
5-
spring.cloud.azure.active-directory.enabled=true
6-
spring.cloud.azure.active-directory.credential.client-id=${AZURE_CLIENT_ID:YOUR_CLIENT_ID}
7-
spring.cloud.azure.active-directory.profile.tenant-id=${AZURE_TENANT_ID:YOUR_TENANT_ID}
8-
spring.cloud.azure.active-directory.app-id-uri=${APP_ID_URI:api://YOUR_CLIENT_ID}
4+
# Entra ID / JWT validation
5+
# Participants set their tenant ID in Exercise 1
6+
spring.security.oauth2.resourceserver.jwt.issuer-uri=${JWT_ISSUER_URI:}
7+
spring.security.oauth2.resourceserver.jwt.audiences=${JWT_AUDIENCE:api://YOUR_API_CLIENT_ID}
98

109
# CORS
1110
app.cors.allowed-origins=${CORS_ALLOWED_ORIGINS:http://localhost:4200}
1211

13-
# Allow bean definition overriding (Spring Cloud Azure + Spring Boot 3.4 conflict)
14-
spring.main.allow-bean-definition-overriding=true
15-
1612
# Default profile
1713
spring.profiles.active=${SPRING_PROFILES_ACTIVE:dev}

0 commit comments

Comments
 (0)