5.9 Build, Run, and Verify
Compile the application, start the Spring Boot server, authenticate an end user through Microsoft Entra ID, and verify that the data grants correctly enforce fine-grained data access control and privilege elevation.
- Terminal 1 (build and run): Use to compile the project, load environment variables, and start the Spring Boot application. This terminal remains occupied while the application runs.
- Terminal 2 (test): Use to generate Proof Key for Code
Exchange (PKCE) values, obtain Entra ID access tokens, and execute
curlrequests against the running API.
5.9.1 Build the Application
Configure your Java and Maven environments, then compile the parent project, the Spring provider module, and the sample API into an executable JAR. Perform these tasks in Terminal 1.
Note:
A successful build ends withBUILD SUCCESS. The executable JAR is located at
target/employee-records-api-0.0.1-SNAPSHOT.jar.
5.9.2 Run the Application
Continuing in Terminal 1, source your environment variables and launch the Spring Boot application.
Note:
If your host requires an HTTP proxy to reach Entra ID, append the following Java Virtual Machine (JVM) arguments to therun
command:mvn -DskipTests spring-boot:run \
-Dspring-boot.run.jvmArguments="\
-Dhttps.proxyHost=<proxy-host> \
-Dhttps.proxyPort=<port> \
-Dhttp.proxyHost=<proxy-host> \
-Dhttp.proxyPort=<port> \
-Dhttp.nonProxyHosts=localhost"5.9.3 Get an Access Token
Switching to Terminal 2, execute the Authorization Code with PKCE flow to simulate a user login, ultimately exchanging an Entra ID authorization code for a JWT access token.
5.9.4 Verify Employee Access
In Terminal 2, call the /api/employees endpoint using
Emma's access token you obtained previously.
curl -s --http1.1 -X GET "http://localhost:8080/api/employees" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Accept: application/json" | python3 -m json.tool
EMPLOYEE in its
roles claim, which activates the EMPLOYEE_ROLE
data role in the database. The EMPLOYEES_OWN_RECORD data grant on
this data role ensures only Emma's record is
returned.[
{
"id": 400,
"name": "Emma Baker",
"salary": 8200,
"phone": "555-0400"
}
]5.9.5 Verify Privilege Elevation
Now, use the same access token and call the
/api/employees/salary-summary endpoint. This demonstrates how the
application temporarily elevates Emma's database privileges, allowing her to view aggregate
salary statistics without exposing individual employee salaries.
curl -s --http1.1 -X GET "http://localhost:8080/api/employees/salary-summary" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Accept: application/json" | python3 -m json.tool
EMPLOYEE role claim,
but for this endpoint the application temporarily activates the
COMPENSATION_ANALYST data role. The corresponding data grant
(EMPLOYEES_SALARY_SUMMARY) allows access to aggregate salary
data across all employees, without exposing individual
records:{
"minSalary": 6900,
"maxSalary": 13000,
"averageSalary": 9826.00,
"employeeCount": 5
}What happens behind the scenes
- The application invokes the
getSalarySummary()method, which is tagged with the@RunWithDataRoles(dataRoles = {"COMPENSATION_ANALYST"})annotation. - A Spring AOP interceptor
(
RunWithDataRolesAopConfig.java) catches this request and temporarily adds thecompensation_analystdata role to Emma’s end-user security context. - The database activates the
hr.employees_salary_summarydata grant, permitting the aggregate salary query. - Emma receives the minimum salary, maximum salary, average salary, and employee count of her team; however, individual salaries remain hidden.
- After the method returns, the privilege elevation is immediately
deactivated. Emma's security context reverts to her standard
EMPLOYEE_ROLEdata role.
This temporary privilege elevation is scoped strictly to the execution of that specific method, controlled by the application, and securely enforced at the database level.