🎯 Mục Tiêu Lab
Hiểu sự khác biệt giữa Application Object và Service Principal trong Microsoft Entra ID
Tạo App Registration với redirect URI và client secret
Phân biệt Delegated Permission và Application Permission
Thêm Microsoft Graph API permission và cấp admin consent
Kiểm tra service principal được tạo tự động trong Enterprise Applications
Hiểu vòng đời và rủi ro bảo mật của client secret
📋 Chuẩn Bị
- Azure subscription đã chuẩn bị từ Lab 01
- Quyền Global Administrator hoặc Application Administrator trên tenant
- Azure CLI phiên bản 2.50+ đã đăng nhập
- Resource group
rg-az500-ch04đã tạo sẵn
- Client secret chỉ hiển thị một lần — copy ngay sau khi tạo
- Không commit client secret lên source control
- Admin consent cấp quyền cho toàn bộ tenant — cần cẩn thận
- Xóa app registration và secret sau khi hoàn thành lab
🏗️ Kịch Bản
Công ty cần phát triển một ứng dụng nội bộ HoaTranLab SecureApp kết nối với Microsoft Graph API để đọc thông tin người dùng và gửi email thông báo bảo mật. Bạn là Azure Security Engineer chịu trách nhiệm đăng ký ứng dụng trong Microsoft Entra ID, cấu hình đúng quyền, và đảm bảo principle of least privilege được áp dụng.
🧪 Các Bước Thực Hiện
Tạo App Registration
Đăng ký ứng dụng mới trong Microsoft Entra ID để tạo định danh cho ứng dụng.
- 1.1Truy cập portal.azure.com → tìm kiếm "Microsoft Entra ID"
- 1.2Menu trái → App registrations → click "+ New registration"
- 1.3Name:
app-az500-secureapp-lab15 - 1.4Supported account types: "Accounts in this organizational directory only (Single tenant)"
- 1.5Redirect URI: Web →
https://localhost:5001/auth/callback - 1.6Click "Register" → ghi lại Application (client) ID và Directory (tenant) ID
# Tạo App Registration
az ad app create \
--display-name "app-az500-secureapp-lab15" \
--sign-in-audience "AzureADMyOrg" \
--web-redirect-uris "https://localhost:5001/auth/callback"
# Lấy Application ID
APP_ID=$(az ad app list \
--display-name "app-az500-secureapp-lab15" \
--query "[0].appId" -o tsv)
echo "Application ID: $APP_ID"
# Lấy tenant ID
TENANT_ID=$(az account show --query tenantId -o tsv)
echo "Tenant ID: $TENANT_ID"
Tạo Client Secret
Client secret là credential ứng dụng dùng để xác thực với Entra ID — tương tự mật khẩu.
- 2.1Trong app registration → menu trái → "Certificates & secrets"
- 2.2Tab "Client secrets" → click "+ New client secret"
- 2.3Description:
secret-lab15-2026, Expires: 90 days - 2.4Click "Add" → copy Value ngay (sẽ không hiển thị lại sau khi rời trang)
# Tạo client secret (thời hạn 90 ngày)
SECRET=$(az ad app credential reset \
--id $APP_ID \
--append \
--display-name "secret-lab15-2026" \
--years 0.25 \
--query "password" -o tsv)
echo "Client Secret Value: $SECRET"
# LƯU Ý: Không expose secret này — chỉ dùng cho lab
# Kiểm tra secret đã tạo (chỉ xem metadata, không xem value)
az ad app credential list --id $APP_ID --output table
Thêm API Permission
Thêm Microsoft Graph API permissions: User.Read (delegated) để đọc profile người dùng đăng nhập, và Mail.Send (delegated) để gửi email nhân danh người dùng.
- 3.1Trong app registration → "API permissions" → "+ Add a permission"
- 3.2Chọn "Microsoft Graph" → "Delegated permissions"
- 3.3Tìm và tick:
User.ReadvàMail.Send→ Add permissions - 3.4Thêm tiếp "Application permissions" → tìm
User.Read.All→ Add - 3.5Nhận xét: User.Read.All (Application) hiển thị cảnh báo "Admin consent required" — đây là quyền mạnh hơn
# Microsoft Graph App ID (constant cho mọi tenant)
GRAPH_APP_ID="00000003-0000-0000-c000-000000000000"
# Permission IDs (lấy từ Graph API reference)
# User.Read (delegated): e1fe6dd8-ba31-4d61-89e7-88639da4683d
# Mail.Send (delegated): e383f46e-2787-4529-855e-0e479a3ffac0
# User.Read.All (application): df021288-bdef-4463-88db-98f22de89214
# Thêm delegated permissions
az ad app permission add \
--id $APP_ID \
--api $GRAPH_APP_ID \
--api-permissions "e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope" \
"e383f46e-2787-4529-855e-0e479a3ffac0=Scope"
# Thêm application permission
az ad app permission add \
--id $APP_ID \
--api $GRAPH_APP_ID \
--api-permissions "df021288-bdef-4463-88db-98f22de89214=Role"
# Xem danh sách permissions đã thêm
az ad app permission list --id $APP_ID --output table
Cấp Admin Consent
Admin consent cho phép ứng dụng sử dụng quyền mà không cần từng người dùng phải đồng ý riêng lẻ — đặc biệt cần thiết cho Application permissions.
- 4.1Trong "API permissions" → click "Grant admin consent for [Tenant Name]"
- 4.2Xác nhận dialog → các permission chuyển sang trạng thái Granted (dấu tích xanh)
- 4.3Quan sát: Delegated permissions được cấp khi user đăng nhập, Application permissions dùng client credential flow
# Grant admin consent cho tất cả permissions đã thêm
az ad app permission admin-consent --id $APP_ID
# Xác nhận consent đã được cấp
az ad app permission list-grants \
--filter "clientId eq '$APP_ID'" \
--output table
Kiểm Tra Service Principal
Mỗi App Registration tạo ra một Application Object (blueprint) và một Service Principal (instance trong tenant). Service Principal là đối tượng thực sự được gán quyền.
- 5.1Entra ID → "Enterprise Applications" → tìm
app-az500-secureapp-lab15 - 5.2Xem Overview: Object ID khác với Application ID trong App Registration
- 5.3Menu trái → "Permissions" → xem Admin consent và User consent đã được cấp
- 5.4Menu trái → "Properties" → ghi nhận App ID, Homepage URL, Assignment required
# Lấy thông tin service principal (object ID khác với app ID)
az ad sp show --id $APP_ID \
--query "{displayName:displayName, appId:appId, objectId:id, servicePrincipalType:servicePrincipalType}" \
--output json
# Xem role assignments của service principal
SP_OBJECT_ID=$(az ad sp show --id $APP_ID --query id -o tsv)
az role assignment list \
--assignee $SP_OBJECT_ID \
--output table
# Xem OAuth2 permission grants
az ad sp show --id $APP_ID \
--query "oauth2PermissionScopes" \
--output table
{
"appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"displayName": "app-az500-secureapp-lab15",
"id": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
"servicePrincipalType": "Application"
}
📊 Kết Quả Đầu Ra Lab 15
Hiển thị trong Entra ID → App registrations với Application ID và Tenant ID
Certificates & secrets hiển thị secret với expiry 90 ngày
User.Read, Mail.Send (delegated) và User.Read.All (application) trong danh sách
Tất cả permissions có trạng thái "Granted for [tenant]" màu xanh
Enterprise Applications có entry với Object ID khác Application ID
Chỉ có permissions cần thiết — không có quyền dư thừa
🧹 Dọn Dẹp
# Xóa client secret trước
az ad app credential delete \
--id $APP_ID \
--key-id $(az ad app credential list --id $APP_ID --query "[0].keyId" -o tsv)
# Xóa app registration (service principal bị xóa theo)
az ad app delete --id $APP_ID
# Xác nhận đã xóa
az ad app list --display-name "app-az500-secureapp-lab15" --output table
❓ Câu Hỏi Ôn Tập
1. Application Object và Service Principal khác nhau như thế nào? Khi nào cần có nhiều Service Principal cho cùng một App Registration?
Gợi ý: Application Object là định nghĩa toàn cục (blueprint), Service Principal là instance trong từng tenant. Multi-tenant app có SP ở nhiều tenant.
2. Delegated Permission và Application Permission khác nhau điểm gì quan trọng về bảo mật?
Gợi ý: Delegated hoạt động trong context của người dùng đăng nhập (giới hạn quyền của user). Application hoạt động không cần user — toàn bộ quyền API.
3. Tại sao nên dùng Certificate thay vì Client Secret? Khi nào bắt buộc phải dùng Certificate?
Gợi ý: Certificate an toàn hơn (private key không rời khỏi máy), workload identity trong Kubernetes thường yêu cầu certificate.
4. Admin consent khác với user consent như thế nào? Khi nào cần admin consent?
Gợi ý: Admin consent áp dụng cho toàn tenant, user consent chỉ cho user đó. Application permissions và một số delegated permissions nhạy cảm bắt buộc admin consent.
5. Làm thế nào để phát hiện app registration có quyền dư thừa (over-privileged)? Công cụ nào trong Azure hỗ trợ?
Gợi ý: Microsoft Entra ID App governance, Permissions Management (CIEM), kiểm tra API permissions trong Enterprise Apps, xem sign-in logs để thấy permissions thực sự được dùng.