Skip to content

Commit 70808a9

Browse files
committed
fix: align workshop guides and deploy scripts with current architecture
- update Exercise 1 to remove Spring Cloud Azure AAD property references - update Exercise 2 to expect 200 (dev profile permits all) instead of 401 - update Exercise 3 to include Step 0 for enabling JWT validation and method security - update configure-app-settings.sh to use JWT_ISSUER_URI and JWT_AUDIENCE env vars - add *.log to .gitignore and remove tracked applicationinsights.log 🔧 - Generated by Copilot
1 parent 8987793 commit 70808a9

6 files changed

Lines changed: 45 additions & 80 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ target/
2525
*.ear
2626
hs_err_pid*
2727
replay_pid*
28+
*.log
2829

2930
# --- IDE ---
3031
.idea/

sample-app/api/applicationinsights.log

Lines changed: 0 additions & 60 deletions
This file was deleted.

scripts/configure-app-settings.sh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ echo "==> Configuring API App Service: ${API_APP_NAME}..."
150150
API_IDENTIFIER_URI="api://${API_CLIENT_ID}"
151151

152152
API_SETTINGS=(
153-
"AZURE_AD_CLIENT_ID=${API_CLIENT_ID}"
154-
"AZURE_AD_TENANT_ID=${TENANT_ID}"
155-
"AZURE_AD_APP_ID_URI=${API_IDENTIFIER_URI}"
153+
"AZURE_TENANT_ID=${TENANT_ID}"
154+
"JWT_ISSUER_URI=https://login.microsoftonline.com/${TENANT_ID}/v2.0"
155+
"JWT_AUDIENCE=${API_IDENTIFIER_URI}"
156156
"AZURE_STORAGE_ACCOUNT_NAME=${STORAGE_ACCOUNT_NAME}"
157157
"AZURE_STORAGE_CONTAINER_NAME=${CONTAINER_NAME}"
158158
"WEBSITES_PORT=8080"
@@ -170,9 +170,9 @@ az webapp config appsettings set \
170170
--output none
171171

172172
echo " API settings configured:"
173-
echo " AZURE_AD_CLIENT_ID"
174-
echo " AZURE_AD_TENANT_ID"
175-
echo " AZURE_AD_APP_ID_URI"
173+
echo " AZURE_TENANT_ID"
174+
echo " JWT_ISSUER_URI"
175+
echo " JWT_AUDIENCE"
176176
echo " AZURE_STORAGE_ACCOUNT_NAME"
177177
echo " AZURE_STORAGE_CONTAINER_NAME"
178178
echo " WEBSITES_PORT=8080"

workshop/guides/exercise-1-app-registrations.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,16 @@ export const environment = {
113113

114114
### Step 10: Update the API Configuration
115115

116-
Open `sample-app/api/src/main/resources/application-dev.properties` and replace the placeholder values:
116+
The API uses standard Spring Security OAuth2 Resource Server for JWT validation. The `dev` profile runs without JWT validation so you can explore the API immediately. For production deployment (Exercise 4), the JWT issuer URI and audience are set via environment variables.
117117

118-
```properties
119-
spring.cloud.azure.active-directory.credential.client-id=<API-CLIENT-ID>
120-
spring.cloud.azure.active-directory.profile.tenant-id=<TENANT-ID>
121-
spring.security.oauth2.resourceserver.jwt.audiences=api://<API-CLIENT-ID>
122-
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://login.microsoftonline.com/<TENANT-ID>/v2.0
123-
```
118+
No changes to `application-dev.properties` are needed at this point. The API configuration is updated during deployment in Exercise 4.
119+
120+
> **Note:** If you want to enable JWT validation locally, set these environment variables before starting the API:
121+
>
122+
> ```bash
123+
> export JWT_ISSUER_URI=https://login.microsoftonline.com/<TENANT-ID>/v2.0
124+
> export JWT_AUDIENCE=api://<API-CLIENT-ID>
125+
> ```
124126
125127
## Scripted Alternative
126128
@@ -144,7 +146,7 @@ Confirm your setup by checking these items:
144146
- [ ] SPA has `Evidence.Read` delegated permission granted
145147
- [ ] SPA is pre-authorized on the API
146148
- [ ] `environment.ts` contains real Client ID, Tenant ID, and scope URI
147-
- [ ] `application-dev.properties` contains real Client ID, Tenant ID, and audience
149+
- [ ] You have recorded the API Client ID, SPA Client ID, and Tenant ID for later exercises
148150

149151
## Troubleshooting
150152

workshop/guides/exercise-2-run-locally.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ mvn spring-boot:run -Dspring-boot.run.profiles=dev
2727

2828
Wait for the log line `Started EvidenceApiApplication` before proceeding. The API runs on `http://localhost:8080`.
2929

30-
### Step 2: Verify the API Requires Authentication
30+
### Step 2: Verify the API Is Running
3131

32-
In a second terminal, send an unauthenticated request:
32+
In a second terminal, send a request:
3333

3434
```bash
35-
curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/api/me
35+
curl -s http://localhost:8080/api/cases | head -c 200
3636
```
3737

38-
Expected result: `401`. This confirms the API rejects requests without a valid Bearer token.
38+
Expected result: a JSON array of 5 mock cases. In the `dev` profile, all endpoints are open for exploration without authentication. JWT validation is enabled when deploying to Azure (Exercise 4).
3939

4040
### Step 3: Install SPA Dependencies and Start the SPA
4141

@@ -103,7 +103,7 @@ Select **Sign Out** in the navigation bar. Verify:
103103

104104
Confirm each of these items works correctly:
105105

106-
- [ ] API starts and returns 401 for unauthenticated requests
106+
- [ ] API starts successfully and returns case data at `http://localhost:8080/api/cases`
107107
- [ ] SPA compiles and loads at `http://localhost:4200`
108108
- [ ] Sign-in redirects to Entra ID and returns an authenticated session
109109
- [ ] Case list loads with sample data

workshop/guides/exercise-3-add-endpoint.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,28 @@ Experience the full role-based access control (RBAC) cycle: attempt a protected
1616

1717
## Steps
1818

19+
### Step 0: Enable JWT Validation and Method Security
20+
21+
The `dev` profile permits all requests and disables `@PreAuthorize` to allow exploration. To experience the RBAC cycle, you must switch to a profile with real JWT validation.
22+
23+
1. Stop the API if it is running (Ctrl+C).
24+
2. Set your Entra ID configuration as environment variables:
25+
26+
```bash
27+
export JWT_ISSUER_URI=https://login.microsoftonline.com/<TENANT-ID>/v2.0
28+
export JWT_AUDIENCE=api://<API-CLIENT-ID>
29+
export SPRING_PROFILES_ACTIVE=prod
30+
```
31+
32+
3. Restart the API:
33+
34+
```bash
35+
cd sample-app/api
36+
mvn spring-boot:run
37+
```
38+
39+
> **Why?** Method security annotations (`@PreAuthorize`) are only enforced in non-dev profiles. The `MethodSecurityConfig` class enables `@EnableMethodSecurity` only for the `!dev` profile.
40+
1941
### Step 1: Examine the POST Endpoint
2042

2143
Open `sample-app/api/src/main/java/com/example/evidence/controller/CaseController.java` and locate the `POST /api/cases` method. Notice the `@PreAuthorize("hasAuthority('ROLE_CaseAdmin')")` annotation. This annotation restricts the endpoint to users whose JWT contains `CaseAdmin` in the `roles` claim.
@@ -128,4 +150,4 @@ If you need to check your work or catch up, solution files are available:
128150
| Role not visible in Enterprise applications | Looking at the App registration instead of Enterprise application | App roles are assigned under **Enterprise applications**, not App registrations |
129151
| `roles` claim missing from JWT | Role assignment did not propagate | Wait 1-2 minutes, sign out, sign back in, and check the token again |
130152
| 500 error on POST instead of 201 | Request body missing required fields | Ensure the JSON body includes `title` and `description` fields |
131-
| `@PreAuthorize` not enforced (any user can POST) | `@EnableMethodSecurity` annotation missing from security configuration | Verify `SecurityConfig.java` has `@EnableMethodSecurity` on the class |
153+
| `@PreAuthorize` not enforced (any user can POST) | Running with the `dev` profile which disables method security | Restart the API with a non-dev profile: set `SPRING_PROFILES_ACTIVE=prod` and provide `JWT_ISSUER_URI` and `JWT_AUDIENCE` environment variables |

0 commit comments

Comments
 (0)