diff --git a/README.md b/README.md
index 4adb9444c..c1d7b889d 100644
--- a/README.md
+++ b/README.md
@@ -21,55 +21,54 @@
## All active branches
-| Spring Boot Version | Spring Cloud version | Spring Cloud Azure Version |
-| --- | --- | --- |
-| 2.5.5 | 2021.0.0 | [4.0](https://github.com/Azure/azure-sdk-for-java/tree/feature/azure-spring-cloud-4.0/sdk/spring) |
+| Spring Boot Version | Spring Cloud version | Spring Cloud Azure Version |
+|----------------------|-----------------------|---------------------------------------------------------------------------------------------------|
+| 2.5.5 | 2021.0.0 | [4.0](https://github.com/Azure/azure-sdk-for-java/tree/feature/azure-spring-cloud-4.0/sdk/spring) |
## All samples in this repo
-| Azure Service | Spring Cloud Azure Starter Dependency | Sample Project |
-|------------------|---------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
+| Azure Service | Spring Cloud Azure Starter Dependency | Sample Project |
+|------------------|---------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------|
| AAD | [spring-cloud-azure-starter-active-directory-b2c:4.0.0-beta.4] | [aad-b2c-resource-server](aad/spring-cloud-azure-starter-active-directory-b2c/aad-b2c-resource-server) |
| AAD | [spring-cloud-azure-starter-active-directory-b2c:4.0.0-beta.4] | [aad-b2c-web-application](aad/spring-cloud-azure-starter-active-directory-b2c/aad-b2c-web-application) |
| AAD | [spring-cloud-azure-starter-active-directory:4.0.0-beta.4] | [aad-resource-server-by-filter-stateless](aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless) |
| AAD | [spring-cloud-azure-starter-active-directory:4.0.0-beta.4] | [aad-resource-server-by-filter](aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter) |
-| AAD | [spring-cloud-azure-starter-active-directory:4.0.0-beta.4] | [aad-resource-server-obo](aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo) |
-| AAD | [spring-cloud-azure-starter-active-directory:4.0.0-beta.4] | [aad-resource-server](aad/spring-cloud-azure-starter-active-directory/aad-resource-server) |
-| AAD | [spring-cloud-azure-starter-active-directory:4.0.0-beta.4] | [aad-web-application](aad/spring-cloud-azure-starter-active-directory/aad-web-application) |
+| AAD | [spring-cloud-azure-starter-active-directory:4.0.0-beta.4] | [web-client-access-resource-server](aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server) |
| AAD | [spring-cloud-azure-starter-active-directory:4.0.0-beta.4] | [aad-webapp-resource-server](aad/spring-cloud-azure-starter-active-directory/aad-web-application-and-resource-server) |
-| App Configuration| [spring-cloud-azure-starter-data-cosmos:4.0.0-beta.4] | [azure-appconfiguration-conversion-sample-initial](appconfiguration/azure-appconfiguration-conversion-sample-initial) |
-| App Configuration| [azure-spring-cloud-appconfiguration-config:2.3.0] | [azure-appconfiguration-sample](appconfiguration/azure-appconfiguration-sample) |
-| App Configuration| [azure-spring-cloud-feature-management:2.2.0] | [feature-management-sample](appconfiguration/feature-management-sample) |
-| App Configuration| [azure-spring-cloud-feature-management:2.2.0] | [feature-management-web-sample](appconfiguration/feature-management-web-sample) |
-| App Configuration| [azure-spring-cloud-appconfiguration-config:2.3.0] | [azure-appconfiguration-conversion-sample-complete](appconfiguration/azure-appconfiguration-conversion-sample-complete) |
-| Cache | N/A | [azure-spring-cloud-sample-cache](cache/spring-cloud-azure-starter/spring-cloud-azure-sample-cache) |
-| Cloud Foundry | N/A | [azure-cloud-foundry-service-sample](cloudfoundry/azure-cloud-foundry-service-sample) |
-| Cosmos DB | [azure-spring-data-cosmos:3.17.0] | [cosmos-multi-database-multi-account](cosmos/azure-spring-data-cosmos/cosmos-multi-database-multi-account) |
-| Cosmos DB | [azure-spring-data-cosmos:3.17.0] | [cosmos-multi-database-single-account](cosmos/azure-spring-data-cosmos/cosmos-multi-database-single-account) |
-| Cosmos DB | [spring-cloud-azure-starter-data-cosmos:4.0.0-beta.4] | [spring-cloud-azure-data-cosmos-sample](cosmos/spring-cloud-azure-starter-data-cosmos/spring-cloud-azure-data-cosmos-sample) |
-| Cosmos DB | [spring-cloud-azure-starter-cosmos:4.0.0-beta.4] | [spring-cloud-azure-cosmos-sample](cosmos/spring-cloud-azure-starter-cosmos/spring-cloud-azure-cosmos-sample) |
-| Event Hubs | N/A | [spring-cloud-azure-sample-eventhubs-kafka](eventhubs/spring-cloud-azure-starter/spring-cloud-azure-sample-eventhubs-kafka) |
-| Event Hubs | [spring-cloud-azure-starter-integration-eventhubs:4.0.0-beta.4] | [eventhubs-integration](eventhubs/spring-cloud-azure-starter-integration-eventhubs/eventhubs-integration) |
-| Event Hubs | [spring-cloud-azure-stream-binder-eventhubs:4.0.0-beta.4] | [eventhubs-binder](eventhubs/spring-cloud-azure-stream-binder-eventhubs/eventhubs-binder) |
-| Event Hubs | [spring-cloud-azure-stream-binder-eventhubs:4.0.0-beta.4] | [eventhubs-multibinders](eventhubs/spring-cloud-azure-stream-binder-eventhubs/eventhubs-multibinders) |
-| Key Vault | [azure-spring-boot-starter-keyvault-certificates:3.13.0] | [keyvault-certificates-client-side](keyvault/azure-spring-boot-starter-keyvault-certificates/keyvault-certificates-client-side) |
-| Key Vault | [azure-spring-boot-starter-keyvault-certificates:3.13.0] | [keyvault-certificates-server-side](keyvault/azure-spring-boot-starter-keyvault-certificates/keyvault-certificates-server-side) |
-| Key Vault | | [run-with-command-line-server-side](keyvault/azure-securtiy-keyvault-jca/run-with-command-line-server-side) |
-| Key Vault | | [run-with-command-line-client-side](keyvault/azure-securtiy-keyvault-jca/run-with-command-line-client-side) |
-| Key Vault | [spring-cloud-azure-starter-keyvault-secrets:4.0.0-beta.4] | [property-source](keyvault/spring-cloud-azure-starter-keyvault-secrets/property-source) |
-| Key Vault | [spring-cloud-azure-starter-keyvault-secrets:4.0.0-beta.4] | [secret-client](keyvault/spring-cloud-azure-starter-keyvault-secrets/secret-client) |
+| App Configuration| [spring-cloud-azure-starter-data-cosmos:4.0.0-beta.4] | [azure-appconfiguration-conversion-sample-initial](appconfiguration/azure-appconfiguration-conversion-sample-initial) |
+| App Configuration| [spring-cloud-azure-starter-data-cosmos:4.0.0-beta.4] | [azure-appconfiguration-conversion-sample-initial](appconfiguration/azure-appconfiguration-conversion-sample-initial) |
+| App Configuration| [azure-spring-cloud-appconfiguration-config:2.3.0] | [azure-appconfiguration-sample](appconfiguration/azure-appconfiguration-sample) |
+| App Configuration| [azure-spring-cloud-feature-management:2.2.0] | [feature-management-sample](appconfiguration/feature-management-sample) |
+| App Configuration| [azure-spring-cloud-feature-management:2.2.0] | [feature-management-web-sample](appconfiguration/feature-management-web-sample) |
+| App Configuration| [azure-spring-cloud-appconfiguration-config:2.3.0] | [azure-appconfiguration-conversion-sample-complete](appconfiguration/azure-appconfiguration-conversion-sample-complete) |
+| Cache | N/A | [azure-spring-cloud-sample-cache](cache/spring-cloud-azure-starter/spring-cloud-azure-sample-cache) |
+| Cloud Foundry | N/A | [azure-cloud-foundry-service-sample](cloudfoundry/azure-cloud-foundry-service-sample) |
+| Cosmos DB | [azure-spring-data-cosmos:3.17.0] | [cosmos-multi-database-multi-account](cosmos/azure-spring-data-cosmos/cosmos-multi-database-multi-account) |
+| Cosmos DB | [azure-spring-data-cosmos:3.17.0] | [cosmos-multi-database-single-account](cosmos/azure-spring-data-cosmos/cosmos-multi-database-single-account) |
+| Cosmos DB | [spring-cloud-azure-starter-data-cosmos:4.0.0-beta.4] | [spring-cloud-azure-data-cosmos-sample](cosmos/spring-cloud-azure-starter-data-cosmos/spring-cloud-azure-data-cosmos-sample) |
+| Cosmos DB | [spring-cloud-azure-starter-cosmos:4.0.0-beta.4] | [spring-cloud-azure-cosmos-sample](cosmos/spring-cloud-azure-starter-cosmos/spring-cloud-azure-cosmos-sample) |
+| Event Hubs | N/A | [spring-cloud-azure-sample-eventhubs-kafka](eventhubs/spring-cloud-azure-starter/spring-cloud-azure-sample-eventhubs-kafka) |
+| Event Hubs | [spring-cloud-azure-starter-integration-eventhubs:4.0.0-beta.4] | [eventhubs-integration](eventhubs/spring-cloud-azure-starter-integration-eventhubs/eventhubs-integration) |
+| Event Hubs | [spring-cloud-azure-stream-binder-eventhubs:4.0.0-beta.4] | [eventhubs-binder](eventhubs/spring-cloud-azure-stream-binder-eventhubs/eventhubs-binder) |
+| Event Hubs | [spring-cloud-azure-stream-binder-eventhubs:4.0.0-beta.4] | [eventhubs-multibinders](eventhubs/spring-cloud-azure-stream-binder-eventhubs/eventhubs-multibinders) |
+| Key Vault | [azure-spring-boot-starter-keyvault-certificates:3.13.0] | [keyvault-certificates-client-side](keyvault/azure-spring-boot-starter-keyvault-certificates/keyvault-certificates-client-side) |
+| Key Vault | [azure-spring-boot-starter-keyvault-certificates:3.13.0] | [keyvault-certificates-server-side](keyvault/azure-spring-boot-starter-keyvault-certificates/keyvault-certificates-server-side) |
+| Key Vault | | [run-with-command-line-server-side](keyvault/azure-securtiy-keyvault-jca/run-with-command-line-server-side) |
+| Key Vault | | [run-with-command-line-client-side](keyvault/azure-securtiy-keyvault-jca/run-with-command-line-client-side) |
+| Key Vault | [spring-cloud-azure-starter-keyvault-secrets:4.0.0-beta.4] | [property-source](keyvault/spring-cloud-azure-starter-keyvault-secrets/property-source) |
+| Key Vault | [spring-cloud-azure-starter-keyvault-secrets:4.0.0-beta.4] | [secret-client](keyvault/spring-cloud-azure-starter-keyvault-secrets/secret-client) |
| Service Bus | [spring-cloud-azure-starter-servicebus-jms:4.0.0-beta.4] | [servicebus-jms-queue](servicebus/spring-cloud-azure-starter-servicebus-jms/servicebus-jms-queue) |
| Service Bus | [spring-cloud-azure-starter-servicebus-jms:4.0.0-beta.4] | [servicebus-jms-topic](servicebus/spring-cloud-azure-starter-servicebus-jms/servicebus-jms-topic) |
-| Service Bus | [spring-cloud-azure-starter-integration-servicebus:4.0.0-beta.4] | [single-namespace](servicebus/spring-cloud-azure-starter-integration-servicebus/single-namespace) |
-| Service Bus | [spring-cloud-azure-starter-integration-servicebus:4.0.0-beta.4] | [multiple-namespaces](servicebus/spring-cloud-azure-starter-integration-servicebus/multiple-namespaces) |
-| Service Bus | [spring-cloud-azure-stream-binder-servicebus:4.0.0-beta.4] | [servicebus-queue-binder](servicebus/spring-cloud-azure-stream-binder-servicebus/servicebus-queue-binder) |
-| Service Bus | [spring-cloud-azure-stream-binder-servicebus:4.0.0-beta.4] | [servicebus-queue-multibinders](servicebus/spring-cloud-azure-stream-binder-servicebus/servicebus-multibinders) |
-| Service Bus | [spring-cloud-azure-stream-binder-servicebus:4.0.0-beta.4] | [servicebus-topic-binder](servicebus/spring-cloud-azure-stream-binder-servicebus/servicebus-topic-binder) |
-| Service Bus | [spring-cloud-azure-stream-binder-servicebus:4.0.0-beta.4] | [servicebus-queue-binder-arm](servicebus/spring-cloud-azure-stream-binder-servicebus/servicebus-queue-binder-arm) |
-| Storage | [spring-cloud-azure-starter-storage-blob:4.0.0-beta.4] | [storage-blob-sample](storage/spring-cloud-azure-starter-storage-blob/storage-blob-sample)
-| Storage | [spring-cloud-azure-starter-storage-file-share:4.0.0-beta.4] | [storage-file-sample](storage/spring-cloud-azure-starter-storage-file-share/storage-file-sample) |
-| Storage | [spring-cloud-azure-starter-integration-storage-queue:4.0.0-beta.4] | [storage-queue-integration](storage/spring-cloud-azure-starter-integration-storage-queue/storage-queue-integration) |
-| Storage | [spring-cloud-azure-starter-integration-storage-queue:4.0.0-beta.4] | [storage-queue-operation](storage/spring-cloud-azure-starter-integration-storage-queue/storage-queue-operation) |
+| Service Bus | [spring-cloud-azure-starter-integration-servicebus:4.0.0-beta.4] | [single-namespace](servicebus/spring-cloud-azure-starter-integration-servicebus/single-namespace) |
+| Service Bus | [spring-cloud-azure-starter-integration-servicebus:4.0.0-beta.4] | [multiple-namespaces](servicebus/spring-cloud-azure-starter-integration-servicebus/multiple-namespaces) |
+| Service Bus | [spring-cloud-azure-stream-binder-servicebus:4.0.0-beta.4] | [servicebus-queue-binder](servicebus/spring-cloud-azure-stream-binder-servicebus/servicebus-queue-binder) |
+| Service Bus | [spring-cloud-azure-stream-binder-servicebus:4.0.0-beta.4] | [servicebus-queue-multibinders](servicebus/spring-cloud-azure-stream-binder-servicebus/servicebus-multibinders) |
+| Service Bus | [spring-cloud-azure-stream-binder-servicebus:4.0.0-beta.4] | [servicebus-topic-binder](servicebus/spring-cloud-azure-stream-binder-servicebus/servicebus-topic-binder) |
+| Service Bus | [spring-cloud-azure-stream-binder-servicebus:4.0.0-beta.4] | [servicebus-queue-binder-arm](servicebus/spring-cloud-azure-stream-binder-servicebus/servicebus-queue-binder-arm) |
+| Storage | [spring-cloud-azure-starter-storage-blob:4.0.0-beta.4] | [storage-blob-sample](storage/spring-cloud-azure-starter-storage-blob/storage-blob-sample)
+| Storage | [spring-cloud-azure-starter-storage-file-share:4.0.0-beta.4] | [storage-file-sample](storage/spring-cloud-azure-starter-storage-file-share/storage-file-sample) |
+| Storage | [spring-cloud-azure-starter-integration-storage-queue:4.0.0-beta.4] | [storage-queue-integration](storage/spring-cloud-azure-starter-integration-storage-queue/storage-queue-integration) |
+| Storage | [spring-cloud-azure-starter-integration-storage-queue:4.0.0-beta.4] | [storage-queue-operation](storage/spring-cloud-azure-starter-integration-storage-queue/storage-queue-operation) |
## Running Samples With Terraform
With [terraform](https://www.terraform.io/) scripts and [DefaultAzureCredential](https://microsoft.github.io/spring-cloud-azure/current/reference/html/index.html#defaultazurecredential), most samples in the project can be run with the same 4 steps below:
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/README.md b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/README.md
index 1b989ebbf..6b3beef44 100644
--- a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/README.md
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/README.md
@@ -5,7 +5,7 @@
This demo project explains the usage of the stateless authentication filter `AadAppRoleStatelessAuthenticationFilter`.
This project is composed of a vue.js frontend and a simple backend with three endpoints
* `/public` (accessible by anyone)
-* `/authorized` (role "user" required)
+* `/authorized` (role "UserRule" required)
* `/admin/demo` (role "admin" required).
## Getting started
@@ -42,11 +42,11 @@ For the test SPA provided with this example you should create the following role
"allowedMemberTypes": [
"User"
],
- "displayName": "User",
+ "displayName": "UserRule",
"id": "f8ed78b5-fabc-488e-968b-baa48a570001",
"isEnabled": true,
"description": "Normal user access",
- "value": "User"
+ "value": "UserRule"
}
],
```
@@ -61,7 +61,11 @@ Furthermore enable the implicit flow in the manifest for the demo application
"oauth2AllowImplicitFlow": "true",
```
-## Examples
+## Running Sample With Terraform
+Please refer to [README.md](terraform/README.md) if you want to start the sample with Terraform in just a few steps.
+
+## Running Sample Step by Step
+
### Configure the sample
#### Configure application.properties
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/src/main/java/com/azure/spring/sample/aad/controller/MainController.java b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/src/main/java/com/azure/spring/sample/aad/controller/MainController.java
index 0d9361ec2..c047c236d 100644
--- a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/src/main/java/com/azure/spring/sample/aad/controller/MainController.java
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/src/main/java/com/azure/spring/sample/aad/controller/MainController.java
@@ -19,7 +19,7 @@ public String publicMethod() {
@GetMapping("/authorized")
@ResponseBody
- @PreAuthorize("hasRole('ROLE_User')")
+ @PreAuthorize("hasRole('ROLE_UserRule')")
public String onlyAuthorizedUsers() {
return "authorized endpoint response";
}
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/README.md b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/README.md
new file mode 100644
index 000000000..628dd4780
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/README.md
@@ -0,0 +1,113 @@
+# Spring Boot application with Azure Active Directory
+
+## What You Need
+
+- [An Azure subscription](https://azure.microsoft.com/free/)
+- [Terraform](https://www.terraform.io/)
+- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
+- [JDK8](https://www.oracle.com/java/technologies/downloads/) or later
+- Maven
+- You can also import the code straight into your IDE:
+ - [IntelliJ IDEA](https://www.jetbrains.com/idea/download)
+
+## Provision Azure Resources Required to Run This Sample
+
+### Authenticate Using the Azure CLI
+Terraform must authenticate to Azure to create infrastructure.
+
+In your terminal, use the Azure CLI tool to setup your account permissions locally.
+
+```shell
+az login --tenant [your-tenant] --allow-no-subscriptions
+```
+
+Your browser window will open and you will be prompted to enter your Azure login credentials. After successful authentication, your terminal will display your subscription information. You do not need to save this output as it is saved in your system for Terraform to use.
+
+```shell
+You have logged in. Now let us find all the subscriptions to which you have access...
+
+[
+ {
+ "cloudName": "AzureCloud",
+ "homeTenantId": "home-Tenant-Id",
+ "id": "subscription-id",
+ "isDefault": true,
+ "managedByTenants": [],
+ "name": "Subscription-Name",
+ "state": "Enabled",
+ "tenantId": "0envbwi39-TenantId",
+ "user": {
+ "name": "your-username@domain.com",
+ "type": "user"
+ }
+ }
+]
+```
+
+### Provision the Resources
+
+After login Azure CLI with your account, now you can use the terraform script to create Azure Resources.
+
+#### Run with Bash
+
+```shell
+# In the root directory of aad-resource-server-by-filter-stateless
+# Initialize your Terraform configuration
+terraform -chdir=./terraform init
+
+# Apply your Terraform Configuration
+terraform -chdir=./terraform apply -auto-approve
+
+```
+
+It may take a few minutes to run the script. After successful running, you will see prompt information like below:
+
+```shell
+...
+Apply complete! Resources: * added, * changed, * destroyed.
+
+```
+
+You can go to [Azure portal](https://ms.portal.azure.com/) in your web browser to check the resources you created.
+
+### Export Output to Your Local Environment
+Running the command below to export environment values:
+
+#### Run with Bash
+
+```shell
+source ./terraform/setup_env.sh
+```
+You will see output like below, save this output to use later.
+```shell
+
+AZURE_CLIENT_ID=...
+AZURE_TENANT_ID=...
+--------created user--------
+USER_NAME=...
+USER_PASSWORD=...
+
+```
+
+## Run Locally
+
+In your current terminal, run `mvn clean spring-boot:run`.
+
+```shell
+mvn clean spring-boot:run
+```
+
+## Verify This Sample
+
+
+## Clean Up Resources
+After running the sample, if you don't want to run the sample, remember to destroy the Azure resources you created to avoid unnecessary billing.
+
+The terraform destroy command terminates resources managed by your Terraform project.
+To destroy the resources you created.
+
+#### Run with Bash
+
+```shell
+terraform -chdir=./terraform destroy -auto-approve
+```
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/main.tf b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/main.tf
new file mode 100644
index 000000000..3abe16310
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/main.tf
@@ -0,0 +1,128 @@
+terraform {
+ required_providers {
+ azuread = {
+ source = "hashicorp/azuread"
+ version = "2.19.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "3.1.0"
+ }
+ null = {
+ source = "hashicorp/null"
+ version = "3.1.0"
+ }
+ }
+}
+
+resource "random_string" "random" {
+ length = 5
+ min_lower = 5
+ special = false
+}
+
+data "azuread_client_config" "current" {}
+
+resource "random_uuid" "role-admin" {
+}
+
+resource "random_uuid" "role-user" {
+}
+
+# Configure the Azure Active Directory Provider
+provider "azuread" {
+}
+
+# Configure an app
+resource "azuread_application" "resourceserver" {
+ display_name = "aad-resource-server-by-filter-stateless-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ sign_in_audience = "AzureADMultipleOrgs"
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "df021288-bdef-4463-88db-98f22de89214" # User.Read.All
+ type = "Role"
+ }
+
+ resource_access {
+ id = "b4e74841-8e56-480b-be8b-910348b18b4c" # User.ReadWrite
+ type = "Scope"
+ }
+
+ resource_access {
+ id = "06da0dbc-49e2-44d2-8312-53f166ab848a" # Directory.Read.All
+ type = "Scope"
+ }
+ }
+
+ single_page_application {
+ redirect_uris = ["http://localhost:8080/"]
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "Full admin access"
+ display_name = "Admin"
+ enabled = true
+ id = random_uuid.role-admin.result
+ value = "Admin"
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "User rule"
+ display_name = "UserRule"
+ enabled = true
+ id = random_uuid.role-user.result
+ value = "UserRule"
+ }
+
+ web {
+ implicit_grant {
+ access_token_issuance_enabled = true
+ id_token_issuance_enabled = true
+ }
+ }
+}
+
+resource "azuread_service_principal" "resourceserver" {
+ application_id = azuread_application.resourceserver.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+# Retrieve domain information
+data "azuread_domains" "current" {
+ only_initial = true
+}
+
+# Create a user
+resource "azuread_user" "user" {
+ user_principal_name = "security-${random_string.random.result}@${data.azuread_domains.current.domains.0.domain_name}"
+ display_name = "security-${random_string.random.result}"
+ password = "Azure123456@"
+}
+
+resource "azuread_app_role_assignment" "admin" {
+ app_role_id = random_uuid.role-admin.result
+ principal_object_id = azuread_user.user.object_id
+ resource_object_id = azuread_service_principal.resourceserver.object_id
+}
+
+resource "azuread_app_role_assignment" "user_role" {
+ app_role_id = random_uuid.role-user.result
+ principal_object_id = azuread_user.user.object_id
+ resource_object_id = azuread_service_principal.resourceserver.object_id
+}
+
+resource "null_resource" "set_env" {
+ depends_on = [azuread_service_principal.resourceserver]
+
+ provisioner "local-exec" {
+ command = "/bin/bash set_identifier_uris.sh"
+ }
+}
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/outputs.tf b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/outputs.tf
new file mode 100644
index 000000000..e6a97ea29
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/outputs.tf
@@ -0,0 +1,20 @@
+output "AZURE_TENANT_ID" {
+ value = data.azuread_client_config.current.tenant_id
+ description = "The Azure tenant id."
+}
+
+output "AZURE_CLIENT_ID" {
+ value = azuread_application.resourceserver.application_id
+ description = "The application id."
+}
+
+output "USER_NAME" {
+ value = azuread_user.user.user_principal_name
+ description = "The user name of the user created by terraform."
+}
+
+output "USER_PASSWORD" {
+ value = azuread_user.user.password
+ sensitive = true
+ description = "The password of the user created by terraform."
+}
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/set_identifier_uris.sh b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/set_identifier_uris.sh
new file mode 100644
index 000000000..3759b610e
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/set_identifier_uris.sh
@@ -0,0 +1,6 @@
+AZURE_CLIENT_ID=$(terraform output -raw AZURE_CLIENT_ID)
+
+# set identifier_uris
+echo "----------update identifier-uris start----------"
+az ad app update --id $AZURE_CLIENT_ID --identifier-uris api://$AZURE_CLIENT_ID
+echo "----------update identifier-uris completed----------"
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/setup_env.sh b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/setup_env.sh
new file mode 100644
index 000000000..331daba8d
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless/terraform/setup_env.sh
@@ -0,0 +1,11 @@
+export AZURE_TENANT_ID=$(terraform -chdir=./terraform output -raw AZURE_TENANT_ID)
+export AZURE_CLIENT_ID=$(terraform -chdir=./terraform output -raw AZURE_CLIENT_ID)
+export USER_NAME=$(terraform -chdir=./terraform output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=./terraform output -raw USER_PASSWORD)
+
+echo AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
+echo AZURE_TENANT_ID=${AZURE_TENANT_ID}
+
+echo "--------created user--------"
+echo USER_NAME=${USER_NAME}
+echo USER_PASSWORD=${USER_PASSWORD}
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/README.md b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/README.md
index bd715a230..40f31e599 100644
--- a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/README.md
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/README.md
@@ -26,7 +26,10 @@ To run this sample, you'll need:
#### Note
- If you are not the admin, you need consent from your admin for the the `Directory.Read.All` permission. For details see [Directory Permissions](https://docs.microsoft.com/graph/permissions-reference#directory-permissions)
-## Examples
+## Running Sample With Terraform
+Please refer to [README.md](terraform/README.md) if you want to start the sample with Terraform in just a few steps.
+
+## Running Sample Step by Step
### Step 1: Clone or download this repository
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/src/main/resources/application.yml b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/src/main/resources/application.yml
index 2c1857ccd..6be328116 100644
--- a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/src/main/resources/application.yml
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/src/main/resources/application.yml
@@ -20,4 +20,4 @@ spring:
user-group:
allowed-group-names: group1,group2
redirect-uri-template: http://localhost:8080/
-
+ jwt-connect-timeout: 5000
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/README.md b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/README.md
new file mode 100644
index 000000000..67fc89344
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/README.md
@@ -0,0 +1,113 @@
+# Spring Boot application with Azure Active Directory
+
+## What You Need
+
+- [An Azure subscription](https://azure.microsoft.com/free/)
+- [Terraform](https://www.terraform.io/)
+- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
+- [JDK8](https://www.oracle.com/java/technologies/downloads/) or later
+- Maven
+- You can also import the code straight into your IDE:
+ - [IntelliJ IDEA](https://www.jetbrains.com/idea/download)
+
+## Provision Azure Resources Required to Run This Sample
+
+### Authenticate Using the Azure CLI
+Terraform must authenticate to Azure to create infrastructure.
+
+In your terminal, use the Azure CLI tool to setup your account permissions locally.
+
+```shell
+az login --tenant [your-tenant] --allow-no-subscriptions
+```
+
+Your browser window will open and you will be prompted to enter your Azure login credentials. After successful authentication, your terminal will display your subscription information. You do not need to save this output as it is saved in your system for Terraform to use.
+
+```shell
+You have logged in. Now let us find all the subscriptions to which you have access...
+
+[
+ {
+ "cloudName": "AzureCloud",
+ "homeTenantId": "home-Tenant-Id",
+ "id": "subscription-id",
+ "isDefault": true,
+ "managedByTenants": [],
+ "name": "Subscription-Name",
+ "state": "Enabled",
+ "tenantId": "0envbwi39-TenantId",
+ "user": {
+ "name": "your-username@domain.com",
+ "type": "user"
+ }
+ }
+]
+```
+
+### Provision the Resources
+
+After login Azure CLI with your account, now you can use the terraform script to create Azure Resources.
+
+#### Run with Bash
+
+```shell
+# In the root directory of aad-resource-server-by-filter
+# Initialize your Terraform configuration
+terraform -chdir=./terraform init
+
+# Apply your Terraform Configuration
+terraform -chdir=./terraform apply -auto-approve
+
+```
+
+It may take a few minutes to run the script. After successful running, you will see prompt information like below:
+
+```shell
+...
+Apply complete! Resources: * added, * changed, * destroyed.
+
+```
+
+You can go to [Azure portal](https://ms.portal.azure.com/) in your web browser to check the resources you created.
+
+### Export Output to Your Local Environment
+Running the command below to export environment values:
+
+#### Run with Bash
+
+```shell
+source ./terraform/setup_env.sh
+```
+
+You will see output like below, save this output of `created user` to login.
+```shell
+...
+--------created user--------
+USER_NAME=...
+USER_PASSWORD=...
+
+```
+
+## Run Locally
+
+In your current terminal, run `mvn clean spring-boot:run`.
+
+```shell
+mvn clean spring-boot:run
+```
+
+## Verify This Sample
+If running locally, browse to http://localhost:8080 and click Login or Todo List, your browser will be redirected to https://login.microsoftonline.com/ for authentication.
+Upon successful login, Todo List will give you a default item and you can perform add, update or delete operation. The backend RESTful API will accept or deny your request based on authenticated user roles.
+
+## Clean Up Resources
+After running the sample, if you don't want to run the sample, remember to destroy the Azure resources you created to avoid unnecessary billing.
+
+The terraform destroy command terminates resources managed by your Terraform project.
+To destroy the resources you created.
+
+#### Run with Bash
+
+```shell
+terraform -chdir=./terraform destroy -auto-approve
+```
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/main.tf b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/main.tf
new file mode 100644
index 000000000..5c0a300a9
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/main.tf
@@ -0,0 +1,104 @@
+terraform {
+ required_providers {
+ azuread = {
+ source = "hashicorp/azuread"
+ version = "2.19.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "3.1.0"
+ }
+ }
+}
+
+resource "random_string" "random" {
+ length = 5
+ min_lower = 5
+ special = false
+}
+
+data "azuread_client_config" "current" {}
+
+# Configure the Azure Active Directory Provider
+provider "azuread" {
+}
+
+# Configure an app
+resource "azuread_application" "aadresourceserverbyfilter" {
+ display_name = "aad-resource-server-by-filter-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ sign_in_audience = "AzureADMultipleOrgs"
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+
+ resource_access {
+ id = "06da0dbc-49e2-44d2-8312-53f166ab848a" # Directory.Read.All
+ type = "Scope"
+ }
+ }
+
+ single_page_application {
+ redirect_uris = ["http://localhost:8080/"]
+ }
+
+ web {
+ implicit_grant {
+ access_token_issuance_enabled = true
+ id_token_issuance_enabled = true
+ }
+ }
+}
+
+resource "azuread_service_principal" "aadresourceserverbyfilter" {
+ application_id = azuread_application.aadresourceserverbyfilter.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_application_password" "aadresourceserverbyfilter" {
+ application_object_id = azuread_application.aadresourceserverbyfilter.object_id
+}
+
+data "azuread_application_published_app_ids" "well_known" {}
+
+resource "azuread_service_principal" "msgraph" {
+ application_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph
+ use_existing = true
+}
+
+resource "azuread_service_principal_delegated_permission_grant" "graph" {
+
+ service_principal_object_id = azuread_service_principal.aadresourceserverbyfilter.object_id
+ resource_service_principal_object_id = azuread_service_principal.msgraph.object_id
+ claim_values = ["Directory.Read.All", "User.Read"]
+}
+
+# Retrieve domain information
+data "azuread_domains" "current" {
+ only_initial = true
+}
+
+# Create a user
+resource "azuread_user" "user" {
+ user_principal_name = "security-${random_string.random.result}@${data.azuread_domains.current.domains.0.domain_name}"
+ display_name = "security-${random_string.random.result}"
+ password = "Azure123456@"
+}
+
+resource "azuread_group" "group1" {
+ display_name = "group1"
+ owners = [data.azuread_client_config.current.object_id]
+ security_enabled = true
+}
+
+resource "azuread_group_member" "group1" {
+ group_object_id = azuread_group.group1.id
+ member_object_id = azuread_user.user.id
+}
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/outputs.tf b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/outputs.tf
new file mode 100644
index 000000000..4ad7c47c5
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/outputs.tf
@@ -0,0 +1,26 @@
+output "AZURE_TENANT_ID" {
+ value = data.azuread_client_config.current.tenant_id
+ description = "The Azure tenant id."
+}
+
+output "AZURE_CLIENT_ID" {
+ value = azuread_application.aadresourceserverbyfilter.application_id
+ description = "The application id."
+}
+
+output "AZURE_CLIENT_SECRET" {
+ value = azuread_application_password.aadresourceserverbyfilter.value
+ sensitive = true
+ description = "A secret string the application uses to prove its identity."
+}
+
+output "USER_NAME" {
+ value = azuread_user.user.user_principal_name
+ description = "The user name of the user created by terraform."
+}
+
+output "USER_PASSWORD" {
+ value = azuread_user.user.password
+ sensitive = true
+ description = "The password of the user created by terraform."
+}
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/setup_env.sh b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/setup_env.sh
new file mode 100644
index 000000000..5585b4410
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter/terraform/setup_env.sh
@@ -0,0 +1,13 @@
+export AZURE_CLIENT_ID=$(terraform -chdir=./terraform output -raw AZURE_CLIENT_ID)
+export AZURE_TENANT_ID=$(terraform -chdir=./terraform output -raw AZURE_TENANT_ID)
+export AZURE_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw AZURE_CLIENT_SECRET)
+export USER_NAME=$(terraform -chdir=./terraform output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=./terraform output -raw USER_PASSWORD)
+
+echo AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
+echo AZURE_TENANT_ID=${AZURE_TENANT_ID}
+echo AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
+
+echo "--------created user--------"
+echo USER_NAME=${USER_NAME}
+echo USER_PASSWORD=${USER_PASSWORD}
diff --git a/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/README.md b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/README.md
new file mode 100644
index 000000000..6a558bf20
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/README.md
@@ -0,0 +1,101 @@
+# Spring Boot application with Azure Active Directory
+
+## What You Need
+
+- [An Azure subscription](https://azure.microsoft.com/free/)
+- [Terraform](https://www.terraform.io/)
+- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
+- [JDK8](https://www.oracle.com/java/technologies/downloads/) or later
+- Maven
+- You can also import the code straight into your IDE:
+ - [IntelliJ IDEA](https://www.jetbrains.com/idea/download)
+
+## Provision Azure Resources Required to Run This Sample
+
+### Authenticate Using the Azure CLI
+Terraform must authenticate to Azure to create infrastructure.
+
+In your terminal, use the Azure CLI tool to setup your account permissions locally.
+
+```shell
+az login --tenant [your-tenant] --allow-no-subscriptions
+```
+
+Your browser window will open and you will be prompted to enter your Azure login credentials. After successful authentication, your terminal will display your subscription information. You do not need to save this output as it is saved in your system for Terraform to use.
+
+```shell
+You have logged in. Now let us find all the subscriptions to which you have access...
+
+[
+ {
+ "cloudName": "AzureCloud",
+ "homeTenantId": "home-Tenant-Id",
+ "id": "subscription-id",
+ "isDefault": true,
+ "managedByTenants": [],
+ "name": "Subscription-Name",
+ "state": "Enabled",
+ "tenantId": "0envbwi39-TenantId",
+ "user": {
+ "name": "your-username@domain.com",
+ "type": "user"
+ }
+ }
+]
+```
+
+### Provision the Resources
+
+After login Azure CLI with your account, now you can use the terraform script to create Azure Resources.
+
+#### Run with Bash
+
+```shell
+# Into the directory of web-client-access-resource-server
+# Initialize your Terraform configuration
+terraform -chdir=./terraform init
+
+# Apply your Terraform Configuration
+terraform -chdir=./terraform apply -auto-approve
+
+```
+
+It may take a few minutes to run the script. After successful running, you will see prompt information like below:
+
+```shell
+...
+Apply complete! Resources: * added, * changed, * destroyed.
+
+```
+
+You can go to [Azure portal](https://ms.portal.azure.com/) in your web browser to check the resources you created.
+
+### Export Output to Your Local Environment
+Running the command below to export environment values:
+
+#### Run with Bash
+
+```shell
+source ./terraform/setup_env.sh
+```
+
+## Run Locally
+
+In your current terminal, run `source run_all.sh`.
+
+```shell
+source run_all.sh
+```
+
+
+## Clean Up Resources
+After running the sample, if you don't want to run the sample, remember to destroy the Azure resources you created to avoid unnecessary billing.
+
+The terraform destroy command terminates resources managed by your Terraform project.
+To destroy the resources you created.
+
+#### Run with Bash
+
+```shell
+terraform -chdir=./terraform destroy -auto-approve
+```
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/README.md b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/README.md
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/README.md
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/README.md
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-aad-obo-flow-and-client-credential-flow.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-aad-obo-flow-and-client-credential-flow.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-aad-obo-flow-and-client-credential-flow.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-aad-obo-flow-and-client-credential-flow.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-add-grant-admin-consent.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-add-grant-admin-consent.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-add-grant-admin-consent.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-add-grant-admin-consent.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-add-permissions.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-add-permissions.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-add-permissions.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-add-permissions.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-resource-server-obo-add-scope.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-resource-server-obo-add-scope.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-resource-server-obo-add-scope.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-resource-server-obo-add-scope.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-select-application-permission.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-select-application-permission.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-select-application-permission.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-select-application-permission.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-select-myapis.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-select-myapis.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/docs/image-select-myapis.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/docs/image-select-myapis.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/pom.xml b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/pom.xml
similarity index 94%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/pom.xml
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/pom.xml
index a0db377eb..64ab8359f 100644
--- a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/pom.xml
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/pom.xml
@@ -7,14 +7,14 @@
com.azure.spring
azure-spring-boot-samples
1.0.0
- ../../../pom.xml
+ ../../../../pom.xml
spring-cloud-azure-starter-active-directory-resource-server-obo
1.0.0
jar
- Spring-Cloud-Azure-Starter-Active-Directory Sample: Resource Server with On-Behalf-of Feature
+ Spring-Cloud-Azure-Starter-Active-Directory Sample: Resource Server with On-Behalf-Of Feature
Azure AD Spring Security Integration Spring Boot Resource Server OBO
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/AadOAuth2ResourceServerOboSampleApplication.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/AadOAuth2ResourceServerOboSampleApplication.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/AadOAuth2ResourceServerOboSampleApplication.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/AadOAuth2ResourceServerOboSampleApplication.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/configuration/AadSampleConfiguration.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/configuration/AadSampleConfiguration.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/configuration/AadSampleConfiguration.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/configuration/AadSampleConfiguration.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/controller/SampleController.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/controller/SampleController.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/controller/SampleController.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/src/main/java/com/azure/spring/sample/aad/controller/SampleController.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/src/main/resources/application.yml b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/src/main/resources/application.yml
similarity index 91%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/src/main/resources/application.yml
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/src/main/resources/application.yml
index 46b2b6e9b..5faad9bad 100644
--- a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo/src/main/resources/application.yml
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server-obo/src/main/resources/application.yml
@@ -15,8 +15,8 @@ spring:
active-directory:
enabled: true
credential:
- client-id: ${AZURE_CLIENT_ID}
- client-secret: ${AZURE_CLIENT_SECRET}
+ client-id: ${WEB_API_A_CLIENT_ID}
+ client-secret: ${WEB_API_A_CLIENT_SECRET}
profile:
tenant-id: ${AZURE_TENANT_ID}
app-id-uri: ${WEB_API_A_APP_ID_URL}
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/README.md b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/README.md
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/README.md
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/README.md
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-add-a-scope.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-add-a-scope.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-add-a-scope.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-add-a-scope.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-add-custom-apis-to-webapp.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-add-custom-apis-to-webapp.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-add-custom-apis-to-webapp.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-add-custom-apis-to-webapp.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-add-resource-server.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-add-resource-server.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-add-resource-server.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-add-resource-server.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-creat-secrets-api.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-creat-secrets-api.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-creat-secrets-api.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-creat-secrets-api.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-expose-api.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-expose-api.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-expose-api.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-expose-api.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-final.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-final.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-final.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-final.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-granted-permission.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-granted-permission.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-granted-permission.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-granted-permission.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-protal-manage.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-protal-manage.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-protal-manage.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-protal-manage.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-register-a-web-api.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-register-a-web-api.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-register-a-web-api.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-register-a-web-api.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-set-application-id-url.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-set-application-id-url.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/docs/image-set-application-id-url.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/docs/image-set-application-id-url.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/pom.xml b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/pom.xml
similarity index 95%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/pom.xml
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/pom.xml
index 9e6030977..f167acaa1 100644
--- a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/pom.xml
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/pom.xml
@@ -7,7 +7,7 @@
com.azure.spring
azure-spring-boot-samples
1.0.0
- ../../../pom.xml
+ ../../../../pom.xml
spring-cloud-azure-starter-active-directory-resource-server
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/src/main/java/com/azure/spring/sample/aad/AadOAuth2ResourceServerSampleApplication.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/src/main/java/com/azure/spring/sample/aad/AadOAuth2ResourceServerSampleApplication.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/src/main/java/com/azure/spring/sample/aad/AadOAuth2ResourceServerSampleApplication.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/src/main/java/com/azure/spring/sample/aad/AadOAuth2ResourceServerSampleApplication.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/src/main/java/com/azure/spring/sample/aad/controller/HomeController.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/src/main/java/com/azure/spring/sample/aad/controller/HomeController.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/src/main/java/com/azure/spring/sample/aad/controller/HomeController.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/src/main/java/com/azure/spring/sample/aad/controller/HomeController.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/src/main/resources/application.yml b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/src/main/resources/application.yml
similarity index 90%
rename from aad/spring-cloud-azure-starter-active-directory/aad-resource-server/src/main/resources/application.yml
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/src/main/resources/application.yml
index ba5e36ad7..02741f509 100644
--- a/aad/spring-cloud-azure-starter-active-directory/aad-resource-server/src/main/resources/application.yml
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-resource-server/src/main/resources/application.yml
@@ -18,8 +18,8 @@ spring:
active-directory:
enabled: true
credential:
- client-id: ${AZURE_CLIENT_ID}
+ client-id: ${WEB_API_B_CLIENT_ID}
profile:
tenant-id: ${AZURE_TENANT_ID}
- app-id-uri: ${APP_ID_URI}
+ app-id-uri: ${WEB_API_B_APP_ID_URI}
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/README.md b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/README.md
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/README.md
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/README.md
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-add-a-platform.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-add-a-platform.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-add-a-platform.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-add-a-platform.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-add-grant-admin-consent.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-add-grant-admin-consent.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-add-grant-admin-consent.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-add-grant-admin-consent.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-add-permissions.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-add-permissions.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-add-permissions.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-add-permissions.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-create-app-secrets.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-create-app-secrets.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-create-app-secrets.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-create-app-secrets.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-permissions.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-permissions.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-permissions.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-permissions.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-portal-manage.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-portal-manage.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-portal-manage.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-portal-manage.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-register-a-web-app.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-register-a-web-app.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-register-a-web-app.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-register-a-web-app.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-request-api-permissions.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-request-api-permissions.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-request-api-permissions.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-request-api-permissions.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-secret-value.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-secret-value.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-secret-value.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-secret-value.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-select-myapis.png b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-select-myapis.png
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/docs/image-select-myapis.png
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/docs/image-select-myapis.png
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/pom.xml b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/pom.xml
similarity index 97%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/pom.xml
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/pom.xml
index adf00117d..87bdf3c5c 100644
--- a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/pom.xml
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/pom.xml
@@ -7,7 +7,7 @@
com.azure.spring
azure-spring-boot-samples
1.0.0
- ../../../pom.xml
+ ../../../../pom.xml
spring-cloud-azure-starter-active-directory-webapp
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/AadOAuth2WebAppSampleApplication.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/AadOAuth2WebAppSampleApplication.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/AadOAuth2WebAppSampleApplication.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/AadOAuth2WebAppSampleApplication.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/config/WebClientConfig.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/config/WebClientConfig.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/config/WebClientConfig.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/config/WebClientConfig.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/AuthorityController.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/AuthorityController.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/AuthorityController.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/AuthorityController.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/ClientController.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/ClientController.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/ClientController.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/ClientController.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/OnDemandClientController.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/OnDemandClientController.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/OnDemandClientController.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/OnDemandClientController.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/RoleController.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/RoleController.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/RoleController.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/RoleController.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/WebApiController.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/WebApiController.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/WebApiController.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/controller/WebApiController.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/utils/JsonMapper.java b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/utils/JsonMapper.java
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/java/com/azure/spring/sample/aad/utils/JsonMapper.java
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/java/com/azure/spring/sample/aad/utils/JsonMapper.java
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/resources/application.yml b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/resources/application.yml
similarity index 69%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/resources/application.yml
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/resources/application.yml
index f2c5f7e6b..523b83bba 100644
--- a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/resources/application.yml
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/resources/application.yml
@@ -31,10 +31,10 @@ spring:
scopes:
- https://graph.microsoft.com/User.Read
- https://graph.microsoft.com/Directory.Read.All
- # webapiA: # This is used to demonstrate on-behalf-of function. Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow
- # scopes:
- # - ${WEB_API_A_APP_ID_URL}/Obo.WebApiA.ExampleScope
- # webapiB: # This is used to demonstrate client_credentials type. Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
- # scopes:
- # - api://${WEB_API_B_APP_ID_URL}/.default
- # authorization-grant-type: client_credentials
\ No newline at end of file
+ webapiA: # This is used to demonstrate on-behalf-of function. Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow
+ scopes:
+ - ${WEB_API_A_APP_ID_URL}/Obo.WebApiA.ExampleScope
+ webapiB: # This is used to demonstrate client_credentials type. Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
+ scopes:
+ - ${WEB_API_B_APP_ID_URL}/.default
+ authorization-grant-type: client_credentials
\ No newline at end of file
diff --git a/aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/resources/templates/index.html b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/resources/templates/index.html
similarity index 100%
rename from aad/spring-cloud-azure-starter-active-directory/aad-web-application/src/main/resources/templates/index.html
rename to aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/aad-web-application/src/main/resources/templates/index.html
diff --git a/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/pom.xml b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/pom.xml
new file mode 100644
index 000000000..66cef4a71
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/pom.xml
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+
+
+ com.azure.spring
+ azure-spring-boot-samples
+ 1.0.0
+ ../../../pom.xml
+
+
+ azure-active-directory-sample-on-behalf-of
+ 1.0.0
+ pom
+
+ Azure Active Directory Sample: On-Behalf-Of
+
+
+ 11
+ 11
+
+
+
+ aad-resource-server
+ aad-resource-server-obo
+ aad-web-application
+
+
+
\ No newline at end of file
diff --git a/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/run_all.sh b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/run_all.sh
new file mode 100644
index 000000000..d0d3829e5
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/run_all.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+
+kill -9 $(lsof -t -i tcp:8080)
+kill -9 $(lsof -t -i tcp:8081)
+kill -9 $(lsof -t -i tcp:8082)
+
+mvn clean package spring-boot:repackage -DskipTests -f ../../../pom.xml -pl \
+com.azure.spring:spring-cloud-azure-starter-active-directory-resource-server,\
+com.azure.spring:spring-cloud-azure-starter-active-directory-resource-server-obo,\
+com.azure.spring:spring-cloud-azure-starter-active-directory-webapp
+
+export AZURE_TENANT_ID=$(terraform -chdir=./terraform output -raw AZURE_TENANT_ID)
+export AZURE_CLIENT_ID=$(terraform -chdir=./terraform output -raw AZURE_CLIENT_ID)
+export AZURE_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw AZURE_CLIENT_SECRET)
+export WEB_API_A_CLIENT_ID=$(terraform -chdir=./terraform output -raw WEB_API_A_CLIENT_ID)
+export WEB_API_A_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw WEB_API_A_CLIENT_SECRET)
+export WEB_API_A_APP_ID_URL=api://$WEB_API_A_CLIENT_ID
+export WEB_API_B_CLIENT_ID=$(terraform -chdir=./terraform output -raw WEB_API_B_CLIENT_ID)
+export WEB_API_B_APP_ID_URL=api://$WEB_API_B_CLIENT_ID
+export WEB_API_C_CLIENT_ID=$(terraform -chdir=./terraform output -raw WEB_API_C_CLIENT_ID)
+export WEB_API_C_APP_ID_URL=api://$WEB_API_C_CLIENT_ID
+
+
+echo "Running apps"
+mkdir -p target
+echo "Running aad-resource-server-----------"
+nohup java -jar aad-resource-server/target/*.jar > target/aad-resource-server.log 2>&1 &
+sleep 3
+echo "Running aad-resource-server-obo-----------"
+nohup java -jar aad-resource-server-obo/target/*.jar > target/aad-resource-server-obo.log 2>&1 &
+sleep 3
+echo "Running aad-web-application-----------"
+nohup java -jar aad-web-application/target/*.jar > target/aad-web-application.log 2>&1 &
+sleep 3
+echo "All apps started, please check target folder for logs."
+echo "You can use the user info below to login."
+echo "--------created user--------"
+# user
+export USER_NAME=$(terraform -chdir=./terraform output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=./terraform output -raw USER_PASSWORD)
+
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+echo "Now you should be able to open browser to access http://localhost:8080 with user above."
+echo "If you encounter some errors, please refer to target folder for app logs ."
diff --git a/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/main.tf b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/main.tf
new file mode 100644
index 000000000..adefc09a4
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/main.tf
@@ -0,0 +1,337 @@
+terraform {
+ required_providers {
+ azuread = {
+ source = "hashicorp/azuread"
+ version = "2.19.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "3.1.0"
+ }
+ null = {
+ source = "hashicorp/null"
+ version = "3.1.0"
+ }
+ }
+}
+
+resource "random_string" "random" {
+ length = 5
+ min_lower = 5
+ special = false
+}
+
+# used to expose api
+resource "random_uuid" "webApiAOboGraph" {
+}
+
+resource "random_uuid" "webApiAOboExample" {
+}
+
+resource "random_uuid" "webApiB" {
+}
+
+resource "random_uuid" "webApiC" {
+}
+
+resource "random_uuid" "WebApiB_ClientCredential_ExampleScope" {
+}
+
+data "azuread_client_config" "current" {}
+
+# Configure the Azure Active Directory Provider
+provider "azuread" {
+}
+
+
+# ====================Configure webApiB====================
+resource "azuread_application" "webApiB" {
+ display_name = "webApiB-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "WebApiB.ExampleScope"
+ admin_consent_display_name = "WebApiB.ExampleScope"
+ enabled = true
+ id = random_uuid.webApiB.result
+ type = "User"
+ value = "WebApiB.ExampleScope"
+ }
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "WebApiB.ClientCredential.ExampleScope"
+ display_name = "WebApiB.ClientCredential.ExampleScope"
+ enabled = true
+ id = random_uuid.WebApiB_ClientCredential_ExampleScope.result
+ value = "WebApiB.ClientCredential.ExampleScope"
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+}
+
+resource "azuread_service_principal" "webApiB" {
+ application_id = azuread_application.webApiB.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+# ====================Configure webapp====================
+resource "azuread_application" "webapp" {
+ display_name = "webapp-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+
+ resource_access {
+ id = "06da0dbc-49e2-44d2-8312-53f166ab848a" # Directory.Read.All
+ type = "Scope"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = "797f4846-ba00-4fd7-ba43-dac1f8f63013" # Azure Service Management
+
+ resource_access {
+ id = "41094075-9dad-400e-a0bd-54e686782033" # user_impersonation
+ type = "Scope"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = azuread_application.webApiB.application_id
+
+ resource_access {
+ id = random_uuid.WebApiB_ClientCredential_ExampleScope.result # WebApiB_ClientCredential_ExampleScope
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/"]
+
+ implicit_grant {
+ access_token_issuance_enabled = true
+ id_token_issuance_enabled = true
+ }
+ }
+}
+
+resource "azuread_service_principal" "webapp" {
+ application_id = azuread_application.webapp.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_application_password" "webapp" {
+ application_object_id = azuread_application.webapp.object_id
+}
+
+data "azuread_application_published_app_ids" "well_known" {}
+
+resource "azuread_service_principal" "msgraph" {
+ application_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph
+ use_existing = true
+}
+
+resource "azuread_service_principal" "management" {
+ application_id = data.azuread_application_published_app_ids.well_known.result.AzureServiceManagement
+ use_existing = true
+}
+
+resource "azuread_service_principal_delegated_permission_grant" "graph" {
+ service_principal_object_id = azuread_service_principal.webapp.object_id
+ resource_service_principal_object_id = azuread_service_principal.msgraph.object_id
+ claim_values = ["Directory.Read.All", "User.Read"]
+}
+
+resource "azuread_service_principal_delegated_permission_grant" "management" {
+ service_principal_object_id = azuread_service_principal.webapp.object_id
+ resource_service_principal_object_id = azuread_service_principal.management.object_id
+ claim_values = ["user_impersonation"]
+}
+
+resource "azuread_service_principal_delegated_permission_grant" "webapp" {
+ service_principal_object_id = azuread_service_principal.webapp.object_id
+ resource_service_principal_object_id = azuread_service_principal.webApiB.object_id
+ claim_values = ["WebApiB_ClientCredential_ExampleScope"]
+}
+
+# ====================Configure webApiC====================
+resource "azuread_application" "webApiC" {
+ display_name = "webApiC-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "WebApiC.ExampleScope"
+ admin_consent_display_name = "WebApiC.ExampleScope"
+ enabled = true
+ id = random_uuid.webApiC.result
+ type = "User"
+ value = "WebApiC.ExampleScope"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+}
+
+resource "azuread_service_principal" "webApiC" {
+ application_id = azuread_application.webApiC.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+# ====================Configure webApiA====================
+resource "azuread_application" "webApiA" {
+ display_name = "webApiA-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "Obo.Graph.Read"
+ admin_consent_display_name = "Obo.Graph.Read"
+ enabled = true
+ id = random_uuid.webApiAOboGraph.result
+ type = "User"
+ value = "Obo.Graph.Read"
+ }
+
+ # `Obo.Graph.Read`
+ oauth2_permission_scope {
+ admin_consent_description = "Obo.Graph.Read"
+ admin_consent_display_name = "Obo.Graph.Read"
+ enabled = true
+ id = random_uuid.webApiAOboGraph.result
+ type = "User"
+ value = "Obo.Graph.Read"
+ }
+
+ # `Obo.WebApiA.ExampleScope`
+ oauth2_permission_scope {
+ admin_consent_description = "Obo.WebApiA.ExampleScope"
+ admin_consent_display_name = "Obo.WebApiA.ExampleScope"
+ enabled = true
+ id = random_uuid.webApiAOboExample.result
+ type = "User"
+ value = "Obo.WebApiA.ExampleScope"
+ }
+
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = azuread_application.webApiB.application_id # webApiB
+
+ # need grant
+ resource_access {
+ id = random_uuid.webApiB.result # WebApiB.ExampleScope
+ type = "Scope"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = azuread_application.webApiC.application_id # webApiC
+
+ # need grant
+ resource_access {
+ id = random_uuid.webApiC.result # WebApiC.ExampleScope
+ type = "Scope"
+ }
+ }
+}
+
+resource "azuread_service_principal" "webApiA" {
+ application_id = azuread_application.webApiA.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_application_password" "webApiA" {
+ application_object_id = azuread_application.webApiA.object_id
+}
+
+resource "azuread_service_principal_delegated_permission_grant" "webApiB" {
+ service_principal_object_id = azuread_service_principal.webApiA.object_id
+ resource_service_principal_object_id = azuread_service_principal.webApiB.object_id
+ claim_values = ["WebApiB.ExampleScope"]
+}
+
+resource "azuread_service_principal_delegated_permission_grant" "webApiC" {
+ service_principal_object_id = azuread_service_principal.webApiA.object_id
+ resource_service_principal_object_id = azuread_service_principal.webApiC.object_id
+ claim_values = ["WebApiC.ExampleScope"]
+}
+
+# Retrieve domain information
+data "azuread_domains" "example" {
+ only_initial = true
+}
+
+# Create a user
+resource "azuread_user" "user" {
+ user_principal_name = "security-${random_string.random.result}@${data.azuread_domains.example.domains.0.domain_name}"
+ display_name = "security-${random_string.random.result}"
+ password = "Azure123456@"
+}
+
+
+resource "null_resource" "set_env" {
+ depends_on = [azuread_service_principal.webApiC]
+
+ provisioner "local-exec" {
+ command = "/bin/bash set_identifier_uris.sh"
+ }
+}
diff --git a/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/outputs.tf b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/outputs.tf
new file mode 100644
index 000000000..2149e144a
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/outputs.tf
@@ -0,0 +1,52 @@
+output "AZURE_TENANT_ID" {
+ value = data.azuread_client_config.current.tenant_id
+ description = "The tenant id."
+}
+
+# ------WEB_APP------
+output "AZURE_CLIENT_ID" {
+ value = azuread_application.webapp.application_id
+ description = "The application id of web app."
+}
+
+output "AZURE_CLIENT_SECRET" {
+ value = azuread_application_password.webapp.value
+ sensitive = true
+ description = "A secret string the application uses to prove its identity."
+}
+
+# ------WebApiA------
+output "WEB_API_A_CLIENT_ID" {
+ value = azuread_application.webApiA.application_id
+ description = "The application id of WebApiA."
+}
+
+output "WEB_API_A_CLIENT_SECRET" {
+ value = azuread_application_password.webApiA.value
+ sensitive = true
+ description = "The client secret of WebApiA."
+}
+
+# ------WebApiB------
+output "WEB_API_B_CLIENT_ID" {
+ value = azuread_application.webApiB.application_id
+ description = "The application id of WebApiB."
+}
+
+# ------WebApiC------
+output "WEB_API_C_CLIENT_ID" {
+ value = azuread_application.webApiC.application_id
+ description = "The application id of WebApiC."
+}
+
+# ------User------
+output "USER_NAME" {
+ value = azuread_user.user.user_principal_name
+ description = "The user name of the user created by terraform."
+}
+
+output "USER_PASSWORD" {
+ value = azuread_user.user.password
+ sensitive = true
+ description = "The password of the user created by terraform."
+}
diff --git a/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/set_identifier_uris.sh b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/set_identifier_uris.sh
new file mode 100644
index 000000000..825608218
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/set_identifier_uris.sh
@@ -0,0 +1,15 @@
+# set identifier_uris
+# webApiA WEB_API_A_CLIENT_ID
+WEB_API_A_CLIENT_ID=$(terraform output -raw WEB_API_A_CLIENT_ID)
+echo "----------update identifier-uris for WEB_API_A----------"
+az ad app update --id $WEB_API_A_CLIENT_ID --identifier-uris api://$WEB_API_A_CLIENT_ID
+
+# webApiB WEB_API_B_CLIENT_ID
+WEB_API_B_CLIENT_ID=$(terraform output -raw WEB_API_B_CLIENT_ID)
+echo "----------update identifier-uris for WEB_API_B----------"
+az ad app update --id $WEB_API_B_CLIENT_ID --identifier-uris api://$WEB_API_B_CLIENT_ID
+
+# webApiC WEB_API_C_CLIENT_ID
+WEB_API_C_CLIENT_ID=$(terraform output -raw WEB_API_C_CLIENT_ID)
+echo "----------update identifier-uris for WEB_API_C----------"
+az ad app update --id $WEB_API_C_CLIENT_ID --identifier-uris api://$WEB_API_C_CLIENT_ID
\ No newline at end of file
diff --git a/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/setup_env.sh b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/setup_env.sh
new file mode 100644
index 000000000..b1043dda0
--- /dev/null
+++ b/aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server/terraform/setup_env.sh
@@ -0,0 +1,53 @@
+terraformpath=./terraform
+export AZURE_TENANT_ID=$(terraform -chdir=$terraformpath output -raw AZURE_TENANT_ID)
+
+# WEB_APP
+export AZURE_CLIENT_ID=$(terraform -chdir=$terraformpath output -raw AZURE_CLIENT_ID)
+export AZURE_CLIENT_SECRET=$(terraform -chdir=$terraformpath output -raw AZURE_CLIENT_SECRET)
+
+# WEB_API_A
+export WEB_API_A_CLIENT_ID=$(terraform -chdir=$terraformpath output -raw WEB_API_A_CLIENT_ID)
+export WEB_API_A_CLIENT_SECRET=$(terraform -chdir=$terraformpath output -raw WEB_API_A_CLIENT_SECRET)
+export WEB_API_A_APP_ID_URL=api://$WEB_API_A_CLIENT_ID
+
+# WEB_API_B
+export WEB_API_B_CLIENT_ID=$(terraform -chdir=$terraformpath output -raw WEB_API_B_CLIENT_ID)
+export WEB_API_B_APP_ID_URL=api://$WEB_API_B_CLIENT_ID
+
+# WEB_API_C
+export WEB_API_C_CLIENT_ID=$(terraform -chdir=$terraformpath output -raw WEB_API_C_CLIENT_ID)
+export WEB_API_C_APP_ID_URL=api://$WEB_API_C_CLIENT_ID
+
+# user
+export USER_PASSWORD=$(terraform -chdir=$terraformpath output -raw USER_PASSWORD)
+export USER_NAME=$(terraform -chdir=$terraformpath output -raw USER_NAME)
+
+# echo================
+echo AZURE_TENANT_ID=$AZURE_TENANT_ID
+
+# WEB_APP
+echo "================WEB_APP================"
+echo AZURE_CLIENT_ID=$AZURE_CLIENT_ID
+echo AZURE_CLIENT_SECRET=$AZURE_CLIENT_SECRET
+
+echo "================WEB_API_A================"
+# WEB_API_A
+echo WEB_API_A_CLIENT_ID=$WEB_API_A_CLIENT_ID
+echo WEB_API_A_CLIENT_SECRET=$WEB_API_A_CLIENT_SECRET
+echo WEB_API_A_APP_ID_URL=$WEB_API_A_APP_ID_URL
+
+# WEB_API_B
+echo "================WEB_API_B================"
+echo WEB_API_B_CLIENT_ID=$WEB_API_B_CLIENT_ID
+echo WEB_API_B_APP_ID_URL=$WEB_API_B_APP_ID_URL
+
+# WEB_API_C
+echo "================WEB_API_C================"
+echo WEB_API_C_CLIENT_ID=$WEB_API_C_CLIENT_ID
+echo WEB_API_C_APP_ID_URL=$WEB_API_C_APP_ID_URL
+
+# user
+echo "===================================="
+echo "--------created user--------"
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
diff --git a/aad/spring-security/docs/reactive/webflux/oauth2/spring-cloud-gateway.md b/aad/spring-security/docs/reactive/webflux/oauth2/spring-cloud-gateway.md
index 73e743af0..ebf2a78da 100644
--- a/aad/spring-security/docs/reactive/webflux/oauth2/spring-cloud-gateway.md
+++ b/aad/spring-security/docs/reactive/webflux/oauth2/spring-cloud-gateway.md
@@ -33,22 +33,23 @@ Get samples applications from in GitHub: [spring-cloud-gateway](../../../../reac
# 3. Create resources in Azure
## 3.1. Create a tenant
-Read [document about creating an Azure AD tenant](https://docs.microsoft.com/azure/active-directory/develop/quickstart-create-new-tenant#create-a-new-azure-ad-tenant), create a new tenant. Get the tenant-id: **${TENANT-ID}**.
+Read [document about creating an Azure AD tenant](https://docs.microsoft.com/azure/active-directory/develop/quickstart-create-new-tenant#create-a-new-azure-ad-tenant), create a new tenant. Get the tenant-id: **${TENANT_ID}**.
+> After creating a new tenant, You can refer to [README.md](../../../../reactive/webflux/oauth2/spring-cloud-gateway/README.md) if you want to start the sample without the knowledge of step by step.
## 3.2. Add a new user
Read [document about adding users](https://docs.microsoft.com/azure/active-directory/fundamentals/add-users-azure-active-directory), add a new user: **user-1@${tenant-name}.com**. Get the user's password.
## 3.3. Register client-1
-Read [document about registering an application](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app), register an application named **client-1**. Get the client-id: **${CLIENT-1-CLIENT-ID}**.
+Read [document about registering an application](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app), register an application named **client-1**. Get the client-id: **${CLIENT_1_CLIENT_ID}**.
## 3.4. Add a client secret for client-1
-Read [document about adding a client secret](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret), add a client secret. Get the client-secret value: **${CLIENT-1-CLIENT-SECRET}**.
+Read [document about adding a client secret](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-client-secret), add a client secret. Get the client-secret value: **${CLIENT_1_CLIENT_SECRET}**.
## 3.5. Add a redirect URI for client-1
Read [document about adding a redirect URI](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app#add-a-redirect-uri), add 2 redirect URIs: **http://localhost:8080/login/oauth2/code/client-1-resource-server-1**, **http://localhost:8080/login/oauth2/code/client-1-resource-server-2**.
## 3.6. Register resource-server-1
-Read [document about registering an application](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app), register an application named **resource-server-1**. Get the client-id: **${RESOURCE-SERVER-1-CLIENT-ID}**.
+Read [document about registering an application](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app), register an application named **resource-server-1**. Get the client-id: **${RESOURCE_SERVER_1_CLIENT_ID}**.
## 3.7. Expose apis for resource-server-1
Read [document about exposing an api](https://docs.microsoft.com/azure/active-directory/develop/quickstart-configure-app-expose-web-apis), expose 2 scopes for resource-server-1: **resource-server-1.scope-1** and **resource-server-1.scope-2**, choose **Admins and users** for **Who can consent** option.
@@ -57,7 +58,7 @@ Read [document about exposing an api](https://docs.microsoft.com/azure/active-di
Read [document about Application manifest](https://docs.microsoft.com/azure/active-directory/develop/reference-app-manifest#accesstokenacceptedversion-attribute), set `accessTokenAcceptedVersion` to `2`.
## 3.9. Register resource-server-2
-Read [document about registering an application](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app), register an application named **resource-server-2**. Get the client-id: **${RESOURCE-SERVER-2-CLIENT-ID}**.
+Read [document about registering an application](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app), register an application named **resource-server-2**. Get the client-id: **${RESOURCE_SERVER_2_CLIENT_ID}**.
## 3.10. Expose apis for resource-server-2
Read [document about exposing an api](https://docs.microsoft.com/azure/active-directory/develop/quickstart-configure-app-expose-web-apis), expose 2 scopes for resource-server-2: **resource-server-2.scope-1** and **resource-server-2.scope-2**, choose **Admins and users** for **Who can consent** option.
diff --git a/aad/spring-security/docs/servlet/oauth2/client-access-multiple-resource-server.md b/aad/spring-security/docs/servlet/oauth2/client-access-multiple-resource-server.md
index dd941453a..0639f36ad 100644
--- a/aad/spring-security/docs/servlet/oauth2/client-access-multiple-resource-server.md
+++ b/aad/spring-security/docs/servlet/oauth2/client-access-multiple-resource-server.md
@@ -33,22 +33,24 @@ Get samples applications from in GitHub: [client-access-multiple-resource-server
# 3. Create resources in Azure
## 3.1. Create a tenant
-Read [document about creating an Azure AD tenant], create a new tenant. Get the tenant-id: **${tenant-id}**.
+Read [document about creating an Azure AD tenant], create a new tenant. Get the tenant-id: **${TENANT_ID}**.
+
+> After creating a new tenant, You can refer to [README.md](../../../servlet/oauth2/client-access-multiple-resource-server/README.md) if you want to start the sample without the knowledge of step by step.
## 3.2. Add a new user
Read [document about adding users], add a new user: **user-1@${tenant-name}.com**. Get the user's password.
## 3.3. Register client-1
-Read [document about registering an application], register an application named **client-1**. Get the client-id: **${client-1-client-id}**.
+Read [document about registering an application], register an application named **client-1**. Get the client-id: **${CLIENT_1_CLIENT_ID}**.
## 3.4. Add a client secret for client-1
-Read [document about adding a client secret], add a client secret. Get the client-secret value: **${client-1-client-secret}**.
+Read [document about adding a client secret], add a client secret. Get the client-secret value: **${CLIENT_1_CLIENT_SECRET}**.
## 3.5. Add a redirect URI for client-1
Read [document about adding a redirect URI], add redirect URI: **http://localhost:8080/login/oauth2/code/**.
## 3.6. Register resource-server-1
-Read [document about registering an application], register an application named **resource-server-1**. Get the client-id: **${resource-server-1-client-id}**.
+Read [document about registering an application], register an application named **resource-server-1**. Get the client-id: **${RESOURCE_SERVER_1_CLIENT_ID}**.
## 3.7. Expose apis for resource-server-1
Read [document about exposing an api], expose 2 scopes for resource-server-1: **resource-server-1.scope-1** and **resource-server-1.scope-2**, choose **Admins and users** for **Who can consent** option.
@@ -57,7 +59,7 @@ Read [document about exposing an api], expose 2 scopes for resource-server-1: **
Read [document about Application manifest], set `accessTokenAcceptedVersion` to `2`.
## 3.9. Register resource-server-2
-Read [document about registering an application], register an application named **resource-server-2**. Get the client-id: **${resource-server-2-client-id}**.
+Read [document about registering an application], register an application named **resource-server-2**. Get the client-id: **${RESOURCE_SERVER_2_CLIENT_ID}**.
## 3.10. Expose apis for resource-server-2
Read [document about exposing an api], expose 2 scopes for resource-server-2: **resource-server-2.scope-1** and **resource-server-2.scope-2**, choose **Admins and users** for **Who can consent** option.
diff --git a/aad/spring-security/docs/servlet/oauth2/client-access-resource-server.md b/aad/spring-security/docs/servlet/oauth2/client-access-resource-server.md
index 36a84af17..51b83c9ba 100644
--- a/aad/spring-security/docs/servlet/oauth2/client-access-resource-server.md
+++ b/aad/spring-security/docs/servlet/oauth2/client-access-resource-server.md
@@ -33,22 +33,23 @@ Get samples applications from in GitHub: [client-access-resource-server].
# 3. Create resources in Azure
## 3.1. Create a tenant
-Read [document about creating an Azure AD tenant], create a new tenant. Get the tenant-id: **${tenant-id}**.
+Read [document about creating an Azure AD tenant], create a new tenant. Get the tenant-id: **${TENANT_ID}**.
+> After creating a new tenant, You can refer to [README.md](../../../servlet/oauth2/client-access-resource-server/README.md) if you want to start the sample without the knowledge of step by step.
## 3.2. Add a new user
Read [document about adding users], add a new user: **user-1@${tenant-name}.com**. Get the user's password.
## 3.3. Register client-1
-Read [document about registering an application], register an application named **client-1**. Get the client-id: **${client-1-client-id}**.
+Read [document about registering an application], register an application named **client-1**. Get the client-id: **${CLIENT_1_CLIENT_ID}**.
## 3.4. Add a client secret for client-1
-Read [document about adding a client secret], add a client secret. Get the client-secret value: **${client-1-client-secret}**.
+Read [document about adding a client secret], add a client secret. Get the client-secret value: **${CLIENT_1_CLIENT_SECRET}**.
## 3.5. Add a redirect URI for client-1
Read [document about adding a redirect URI], add redirect URI: **http://localhost:8080/login/oauth2/code/**.
## 3.6. Register resource-server-1
-Read [document about registering an application], register an application named **resource-server-1**. Get the client-id: **${resource-server-1-client-id}**.
+Read [document about registering an application], register an application named **resource-server-1**. Get the client-id: **${RESOURCE_SERVER_1_CLIENT_ID}**.
## 3.7. Expose apis for resource-server-1
Read [document about exposing an api], expose 2 scopes for resource-server-1: **resource-server-1.scope-1** and **resource-server-1.scope-2**, choose **Admins and users** for **Who can consent** option.
diff --git a/aad/spring-security/docs/servlet/oauth2/login.md b/aad/spring-security/docs/servlet/oauth2/login.md
index 67eefa2db..d9ab09038 100644
--- a/aad/spring-security/docs/servlet/oauth2/login.md
+++ b/aad/spring-security/docs/servlet/oauth2/login.md
@@ -27,16 +27,17 @@ Get samples applications from in GitHub: [login].
# 3. Create resources in Azure
## 3.1. Create a tenant
-Read [document about creating an Azure AD tenant], create a new tenant. Get the tenant-id: **${tenant-id}**.
+Read [document about creating an Azure AD tenant], create a new tenant. Get the tenant-id: **${TENANT_ID}**.
+> After creating a new tenant, You can refer to [README] if you want to start the sample without the knowledge of step by step.
## 3.2. Add a new user
Read [document about adding users], add a new user: **user-1@${tenant-name}.com**. Get the user's password.
## 3.3. Register client-1
-Read [document about registering an application], register an application named **client-1**. Get the client-id: **${client-1-client-id}**.
+Read [document about registering an application], register an application named **client-1**. Get the client-id: **${CLIENT_1_CLIENT_ID}**.
## 3.4. Add a client secret for client-1
-Read [document about adding a client secret], add a client secret. Get the client-secret value: **${client-1-client-secret}**.
+Read [document about adding a client secret], add a client secret. Get the client-secret value: **${CLIENT_1_CLIENT_SECRET}**.
## 3.5. Add a redirect URI for client-1
Read [document about adding a redirect URI], add redirect URI: **http://localhost:8080/login/oauth2/code/**.
@@ -76,6 +77,7 @@ Read [document about adding a redirect URI], add redirect URI: **http://localhos
[document about exposing an api]: https://docs.microsoft.com/azure/active-directory/develop/quickstart-configure-app-expose-web-apis
[document about Application manifest]: https://docs.microsoft.com/azure/active-directory/develop/reference-app-manifest#accesstokenacceptedversion-attribute
[login]: ../../../servlet/oauth2/login
+[README]: ../../../servlet/oauth2/login/README.md
[Edge]: https://www.microsoft.com/edge?r=1
[InPrivate window]: https://support.microsoft.com/microsoft-edge/browse-inprivate-in-microsoft-edge-cd2c9a48-0bc4-b98e-5e46-ac40c84e27e2
[rfc6749]: https://datatracker.ietf.org/doc/html/rfc6749
diff --git a/aad/spring-security/docs/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token.md b/aad/spring-security/docs/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token.md
index eec10b97e..46e5485bf 100644
--- a/aad/spring-security/docs/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token.md
+++ b/aad/spring-security/docs/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token.md
@@ -35,22 +35,23 @@ Get samples applications from in GitHub: [resource-server-check-permissions-by-c
# 3. Create resources in Azure
## 3.1. Create a tenant
-Read [document about creating an Azure AD tenant], create a new tenant. Get the tenant-id: **${tenant-id}**.
+Read [document about creating an Azure AD tenant], create a new tenant. Get the tenant-id: **${TENANT_ID}**.
+> After creating a new tenant, You can refer to [README.md](../../../servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/README.md) if you want to start the sample without the knowledge of step by step.
## 3.2. Add a new user
Read [document about adding users], add a new user: **user-1@${tenant-name}.com**. Get the user's password.
## 3.3. Register client-1
-Read [document about registering an application], register an application named **client-1**. Get the client-id: **${client-1-client-id}**.
+Read [document about registering an application], register an application named **client-1**. Get the client-id: **${CLIENT_1_CLIENT_ID}**.
## 3.4. Add a client secret for client-1
-Read [document about adding a client secret], add a client secret. Get the client-secret value: **${client-1-client-secret}**.
+Read [document about adding a client secret], add a client secret. Get the client-secret value: **${CLIENT_1_CLIENT_SECRET}**.
## 3.5. Add a redirect URI for client-1
Read [document about adding a redirect URI], add redirect URI: **http://localhost:8080/login/oauth2/code/**.
## 3.6. Register resource-server-1
-Read [document about registering an application], register an application named **resource-server-1**. Get the client-id: **${resource-server-1-client-id}**.
+Read [document about registering an application], register an application named **resource-server-1**. Get the client-id: **${RESOURCE_SERVER_1_CLIENT_ID}**.
## 3.7. Expose apis for resource-server-1
Read [document about exposing an api], expose 2 scopes for resource-server-1: **resource-server-1.scope-1** and **resource-server-1.scope-2**, choose **Admins and users** for **Who can consent** option.
diff --git a/aad/spring-security/docs/servlet/oauth2/resource-server-support-on-behalf-of-flow.md b/aad/spring-security/docs/servlet/oauth2/resource-server-support-on-behalf-of-flow.md
index 460bf3b87..c56840b72 100644
--- a/aad/spring-security/docs/servlet/oauth2/resource-server-support-on-behalf-of-flow.md
+++ b/aad/spring-security/docs/servlet/oauth2/resource-server-support-on-behalf-of-flow.md
@@ -40,25 +40,26 @@ Get samples applications from in GitHub: [resource-server-support-on-behalf-of-f
# 3. Create resources in Azure
## 3.1. Create a tenant
-Read [document about creating an Azure AD tenant], create a new tenant. Get the tenant-id: **${tenant-id}**.
+Read [document about creating an Azure AD tenant], create a new tenant. Get the tenant-id: **${TENANT_ID}**.
+> After creating a new tenant, You can refer to [README.md](../../../servlet/oauth2/resource-server-support-on-behalf-of-flow/README.md) if you want to start the sample without the knowledge of step by step.
## 3.2. Add a new user
Read [document about adding users], add a new user: **user-1@${tenant-name}.com**. Get the user's password.
## 3.3. Register client-1
-Read [document about registering an application], register an application named **client-1**. Get the client-id: **${client-1-client-id}**.
+Read [document about registering an application], register an application named **client-1**. Get the client-id: **${CLIENT_1_CLIENT_ID}**.
## 3.4. Add a client secret for client-1
-Read [document about adding a client secret], add a client secret. Get the client-secret value: **${client-1-client-secret}**.
+Read [document about adding a client secret], add a client secret. Get the client-secret value: **${CLIENT_1_CLIENT_SECRET}**.
## 3.5. Add a redirect URI for client-1
Read [document about adding a redirect URI], add redirect URI: **http://localhost:8080/login/oauth2/code/**.
## 3.6. Register resource-server-1
-Read [document about registering an application], register an application named **resource-server-1**. Get the client-id: **${resource-server-1-client-id}**.
+Read [document about registering an application], register an application named **resource-server-1**. Get the client-id: **${RESOURCE_SERVER_1_CLIENT_ID}**.
## 3.7. Add a client secret for resource-server-1
-Read [document about adding a client secret], add a client secret. Get the client-secret value: **${resource-server-1-client-secret}**.
+Read [document about adding a client secret], add a client secret. Get the client-secret value: **${RESOURCE_SERVER_1_CLIENT_SECRET}**.
## 3.8. Add a redirect URI for resource-server-1
Read [document about adding a redirect URI], add redirect URI: **http://localhost:8080/login/oauth2/code/**.
@@ -70,7 +71,7 @@ Read [document about exposing an api], expose 2 scopes for resource-server-1: **
Read [document about Application manifest], set `accessTokenAcceptedVersion` to `2`.
## 3.11. Register resource-server-2
-Read [document about registering an application], register an application named **resource-server-2**. Get the client-id: **${resource-server-2-client-id}**.
+Read [document about registering an application], register an application named **resource-server-2**. Get the client-id: **${RESOURCE_SERVER_2_CLIENT_ID}**.
## 3.12. Expose apis for resource-server-2
Read [document about exposing an api], expose 2 scopes for resource-server-2: **resource-server-2.scope-1** and **resource-server-2.scope-2**, choose **Admins and users** for **Who can consent** option.
diff --git a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/README.md b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/README.md
new file mode 100644
index 000000000..15d498031
--- /dev/null
+++ b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/README.md
@@ -0,0 +1,103 @@
+# Spring Boot application with Azure Active Directory
+
+## What You Need
+
+- [An Azure subscription](https://azure.microsoft.com/free/)
+- [Terraform](https://www.terraform.io/)
+- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
+- [JDK8](https://www.oracle.com/java/technologies/downloads/) or later
+- Maven
+- You can also import the code straight into your IDE:
+ - [IntelliJ IDEA](https://www.jetbrains.com/idea/download)
+
+## Provision Azure Resources Required to Run This Sample
+
+### Authenticate Using the Azure CLI
+Terraform must authenticate to Azure to create infrastructure.
+
+In your terminal, use the Azure CLI tool to setup your account permissions locally.
+
+```shell
+az login --tenant [your-tenant] --allow-no-subscriptions
+```
+
+Your browser window will open and you will be prompted to enter your Azure login credentials. After successful authentication, your terminal will display your subscription information. You do not need to save this output as it is saved in your system for Terraform to use.
+
+```shell
+You have logged in. Now let us find all the subscriptions to which you have access...
+
+[
+ {
+ "cloudName": "AzureCloud",
+ "homeTenantId": "home-Tenant-Id",
+ "id": "subscription-id",
+ "isDefault": true,
+ "managedByTenants": [],
+ "name": "Subscription-Name",
+ "state": "Enabled",
+ "tenantId": "0envbwi39-TenantId",
+ "user": {
+ "name": "your-username@domain.com",
+ "type": "user"
+ }
+ }
+]
+```
+
+### Provision the Resources
+
+After login Azure CLI with your account, now you can use the terraform script to create Azure Resources.
+
+#### Run with Bash
+
+```shell
+# Into the directory of spring-cloud-gateway
+# Initialize your Terraform configuration
+terraform -chdir=./terraform init
+
+# Apply your Terraform Configuration
+terraform -chdir=./terraform apply -auto-approve
+
+```
+
+It may take a few minutes to run the script. After successful running, you will see prompt information like below:
+
+```shell
+...
+Apply complete! Resources: * added, * changed, * destroyed.
+
+```
+
+You can go to [Azure portal](https://ms.portal.azure.com/) in your web browser to check the resources you created.
+
+### Export Output to Your Local Environment
+Running the command below to export environment values:
+
+#### Run with Bash
+
+```shell
+source ./terraform/setup_env.sh
+```
+
+## Run Locally
+
+In your current terminal, run `source run_all.sh`.
+
+```shell
+source run_all.sh
+```
+
+## Verify This Sample
+
+
+## Clean Up Resources
+After running the sample, if you don't want to run the sample, remember to destroy the Azure resources you created to avoid unnecessary billing.
+
+The terraform destroy command terminates resources managed by your Terraform project.
+To destroy the resources you created.
+
+#### Run with Bash
+
+```shell
+terraform -chdir=./terraform destroy -auto-approve
+```
diff --git a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/client/src/main/resources/application.yml b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/client/src/main/resources/application.yml
index 3406730fb..c14e17540 100644
--- a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/client/src/main/resources/application.yml
+++ b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/client/src/main/resources/application.yml
@@ -1,9 +1,9 @@
# Please fill these placeholders before running this application:
-# 1. ${TENANT-ID}
-# 2. ${CLIENT-1-CLIENT-ID}
-# 3. ${CLIENT-1-CLIENT-SECRET}
-# 4. ${RESOURCE-SERVER-1-CLIENT-ID}
-# 5. ${RESOURCE-SERVER-2-CLIENT-ID}
+# 1. ${TENANT_ID}
+# 2. ${CLIENT_1_CLIENT_ID}
+# 3. ${CLIENT_1_CLIENT_SECRET}
+# 4. ${RESOURCE_SERVER_1_CLIENT_ID}
+# 5. ${RESOURCE_SERVER_2_CLIENT_ID}
logging:
level:
@@ -16,20 +16,20 @@ spring:
client:
provider: # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login-common-oauth2-provider
azure-active-directory:
- issuer-uri: https://login.microsoftonline.com/${TENANT-ID}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
user-name-attribute: name
registration:
client-1-resource-server-1:
provider: azure-active-directory
client-name: client-1-resource-server-1
- client-id: ${CLIENT-1-CLIENT-ID}
- client-secret: ${CLIENT-1-CLIENT-SECRET}
- scope: api://${RESOURCE-SERVER-1-CLIENT-ID}/resource-server-1.scope-1
+ client-id: ${CLIENT_1_CLIENT_ID}
+ client-secret: ${CLIENT_1_CLIENT_SECRET}
+ scope: api://${RESOURCE_SERVER_1_CLIENT_ID}/resource-server-1.scope-1
client-1-resource-server-2:
provider: azure-active-directory
client-name: client-1-resource-server-2
- client-id: ${CLIENT-1-CLIENT-ID}
- client-secret: ${CLIENT-1-CLIENT-SECRET}
- scope: api://${RESOURCE-SERVER-2-CLIENT-ID}/resource-server-2.scope-1
+ client-id: ${CLIENT_1_CLIENT_ID}
+ client-secret: ${CLIENT_1_CLIENT_SECRET}
+ scope: api://${RESOURCE_SERVER_2_CLIENT_ID}/resource-server-2.scope-1
profiles:
active: develop
diff --git a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/gateway/src/main/resources/application.yml b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/gateway/src/main/resources/application.yml
index d66ee190f..3fa0ec97f 100644
--- a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/gateway/src/main/resources/application.yml
+++ b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/gateway/src/main/resources/application.yml
@@ -1,7 +1,7 @@
# Please fill these placeholders before running this application:
-# 1. ${TENANT-ID}
-# 4. ${RESOURCE-SERVER-1-CLIENT-ID}
-# 5. ${RESOURCE-SERVER-2-CLIENT-ID}
+# 1. ${TENANT_ID}
+# 4. ${RESOURCE_SERVER_1_CLIENT_ID}
+# 5. ${RESOURCE_SERVER_2_CLIENT_ID}
logging:
level:
@@ -26,8 +26,8 @@ spring:
oauth2:
resourceserver:
jwt:
- jwk-set-uri: https://login.microsoftonline.com/${TENANT-ID}/discovery/v2.0/keys
- issuer-uri: https://login.microsoftonline.com/${TENANT-ID}/v2.0
- audiences: ${RESOURCE-SERVER-1-CLIENT-ID}, ${RESOURCE-SERVER-2-CLIENT-ID}
+ jwk-set-uri: https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0
+ audiences: ${RESOURCE_SERVER_1_CLIENT_ID}, ${RESOURCE_SERVER_2_CLIENT_ID}
profiles:
active: develop
diff --git a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/resource-server-1/src/main/resources/application.yml b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/resource-server-1/src/main/resources/application.yml
index 16d9a9986..ae4cd6424 100644
--- a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/resource-server-1/src/main/resources/application.yml
+++ b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/resource-server-1/src/main/resources/application.yml
@@ -1,6 +1,6 @@
# Please fill these placeholders before running this application:
-# 1. ${TENANT-ID}
-# 2. ${RESOURCE-SERVER-1-CLIENT-ID}
+# 1. ${TENANT_ID}
+# 2. ${RESOURCE_SERVER_1_CLIENT_ID}
logging:
level:
@@ -12,8 +12,8 @@ spring:
oauth2:
resourceserver:
jwt:
- jwk-set-uri: https://login.microsoftonline.com/${TENANT-ID}/discovery/v2.0/keys
- issuer-uri: https://login.microsoftonline.com/${TENANT-ID}/v2.0
- audiences: ${RESOURCE-SERVER-1-CLIENT-ID}
+ jwk-set-uri: https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0
+ audiences: ${RESOURCE_SERVER_1_CLIENT_ID}
profiles:
active: develop
diff --git a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/resource-server-2/src/main/resources/application.yml b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/resource-server-2/src/main/resources/application.yml
index a617cfdd2..f4a1e0ada 100644
--- a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/resource-server-2/src/main/resources/application.yml
+++ b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/resource-server-2/src/main/resources/application.yml
@@ -1,6 +1,6 @@
# Please fill these placeholders before running this application:
-# 1. ${TENANT-ID}
-# 2. ${RESOURCE-SERVER-2-CLIENT-ID}
+# 1. ${TENANT_ID}
+# 2. ${RESOURCE_SERVER_2_CLIENT_ID}
logging:
level:
@@ -12,8 +12,8 @@ spring:
oauth2:
resourceserver:
jwt:
- jwk-set-uri: https://login.microsoftonline.com/${TENANT-ID}/discovery/v2.0/keys
- issuer-uri: https://login.microsoftonline.com/${TENANT-ID}/v2.0
- audiences: ${RESOURCE-SERVER-2-CLIENT-ID}
+ jwk-set-uri: https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0
+ audiences: ${RESOURCE_SERVER_2_CLIENT_ID}
profiles:
active: develop
diff --git a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/run_all.sh b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/run_all.sh
new file mode 100644
index 000000000..e5e9f483b
--- /dev/null
+++ b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/run_all.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env bash
+
+kill -9 $(lsof -t -i tcp:8080)
+kill -9 $(lsof -t -i tcp:8081)
+kill -9 $(lsof -t -i tcp:8082)
+kill -9 $(lsof -t -i tcp:8083)
+
+mvn clean package spring-boot:repackage -DskipTests -f ../../../../pom.xml -pl \
+com.azure.spring:spring-security-sample-reactive-webflux-oauth2-spring-cloud-gateway-client-application,\
+com.azure.spring:spring-security-sample-reactive-webflux-oauth2-spring-cloud-gateway-gateway-application,\
+com.azure.spring:spring-security-sample-reactive-webflux-oauth2-spring-cloud-gateway-resource-server-1-application,\
+com.azure.spring:spring-security-sample-reactive-webflux-oauth2-spring-cloud-gateway-resource-server-2-application
+
+export terraform_path="./terraform"
+
+export TENANT_ID=$(terraform -chdir=$terraform_path output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw CLIENT_1_CLIENT_ID)
+export RESOURCE_SERVER_1_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_1_CLIENT_ID)
+export RESOURCE_SERVER_2_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_2_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=$terraform_path output -raw CLIENT_1_CLIENT_SECRET)
+export RESOURCE_SERVER_1_CLIENT_SECRET=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_1_CLIENT_SECRET)
+export USER_NAME=$(terraform -chdir=$terraform_path output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=$terraform_path output -raw USER_PASSWORD)
+
+
+echo "--------Running apps--------"
+mkdir -p target
+sleep 3
+echo "--------Running client--------"
+nohup java -jar client/target/*.jar > target/client.log 2>&1 &
+sleep 3
+echo "--------Running gateway--------"
+nohup java -jar gateway/target/*.jar > target/gateway.log 2>&1 &
+sleep 3
+echo "--------Running resource-server-1--------"
+nohup java -jar resource-server-1/target/*.jar > target/resource-server-1.log 2>&1 &
+sleep 3
+echo "--------Running resource-server-2--------"
+nohup java -jar resource-server-2/target/*.jar > target/resource-server-2.log 2>&1 &
+
+echo "All apps started, please check target folder for logs."
+echo "You can use the user info below to login."
+echo "--------created user--------"
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+echo "Now you should be able to open browser to access http://localhost:8080 with user above."
+echo "If you encounter some errors, please refer to target folder for app logs ."
\ No newline at end of file
diff --git a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/main.tf b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/main.tf
new file mode 100644
index 000000000..9a8727317
--- /dev/null
+++ b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/main.tf
@@ -0,0 +1,247 @@
+terraform {
+ required_providers {
+ azuread = {
+ source = "hashicorp/azuread"
+ version = "2.19.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "3.1.0"
+ }
+ null = {
+ source = "hashicorp/null"
+ version = "3.1.0"
+ }
+ }
+}
+
+resource "random_string" "random" {
+ length = 5
+ min_lower = 5
+ special = false
+}
+
+resource "random_uuid" "resource-server-1-scope-1" {
+}
+
+resource "random_uuid" "resource-server-1-scope-2" {
+}
+
+resource "random_uuid" "resource-server-2-scope-1" {
+}
+
+resource "random_uuid" "resource-server-2-scope-2" {
+}
+
+resource "random_uuid" "resource-server-1-role-1" {
+}
+
+resource "random_uuid" "resource-server-1-role-2" {
+}
+
+data "azuread_client_config" "current" {}
+
+# Configure the Azure Active Directory Provider
+provider "azuread" {
+}
+
+# Configure client-1
+resource "azuread_application" "client-1" {
+ display_name = "client-1"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/",
+ "http://localhost:8080/login/oauth2/code/client-1-resource-server-1",
+ "http://localhost:8080/login/oauth2/code/client-1-resource-server-2"]
+
+ implicit_grant {
+ access_token_issuance_enabled = true
+ id_token_issuance_enabled = true
+ }
+ }
+}
+
+
+# Configure resource-server-2
+resource "azuread_application" "resource-server-2" {
+ display_name = "resource-server-2"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-2.scope-1"
+ admin_consent_display_name = "resource-server-2.scope-1"
+ enabled = true
+ id = random_uuid.resource-server-2-scope-1.result
+ type = "User"
+ value = "resource-server-2.scope-1"
+ }
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-2.scope-2"
+ admin_consent_display_name = "resource-server-2.scope-2"
+ enabled = true
+ id = random_uuid.resource-server-2-scope-2.result
+ type = "User"
+ value = "resource-server-2.scope-2"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+}
+
+
+# Configure resource-server-1
+resource "azuread_application" "resource-server-1" {
+ display_name = "resource-server-1"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-1.scope-1"
+ admin_consent_display_name = "resource-server-1.scope-1"
+ enabled = true
+ id = random_uuid.resource-server-1-scope-1.result
+ type = "User"
+ value = "resource-server-1.scope-1"
+ }
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-1.scope-2"
+ admin_consent_display_name = "resource-server-1.scope-2"
+ enabled = true
+ id = random_uuid.resource-server-1-scope-2.result
+ type = "User"
+ value = "resource-server-1.scope-2"
+ }
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "resource-server-1-role-2"
+ display_name = "resource-server-1-role-2"
+ enabled = true
+ id = random_uuid.resource-server-1-role-2.result
+ value = "resource-server-1-role-2"
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "resource-server-1-role-1"
+ display_name = "resource-server-1-role-1"
+ enabled = true
+ id = random_uuid.resource-server-1-role-1.result
+ value = "resource-server-1-role-1"
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = azuread_application.resource-server-2.application_id # Resource server 2
+
+ # need grant
+ resource_access {
+ id = random_uuid.resource-server-2-scope-1.result # resource-server-2.scope-1
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/"]
+ }
+}
+
+resource "azuread_service_principal_delegated_permission_grant" "resource-server-1" {
+ service_principal_object_id = azuread_service_principal.resource-server-1.object_id
+ resource_service_principal_object_id = azuread_service_principal.resource-server-2.object_id
+ claim_values = ["resource-server-2.scope-1"]
+}
+
+resource "azuread_service_principal" "client-1" {
+ application_id = azuread_application.client-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_service_principal" "resource-server-1" {
+ application_id = azuread_application.resource-server-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_service_principal" "resource-server-2" {
+ application_id = azuread_application.resource-server-2.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+
+resource "azuread_application_password" "client-1" {
+ application_object_id = azuread_application.client-1.object_id
+}
+
+
+resource "azuread_application_password" "resource-server-1" {
+ application_object_id = azuread_application.resource-server-1.object_id
+}
+
+# Retrieve domain information
+data "azuread_domains" "example" {
+ only_initial = true
+}
+
+# Create a user
+resource "azuread_user" "user" {
+ user_principal_name = "security-${random_string.random.result}@${data.azuread_domains.example.domains.0.domain_name}"
+ display_name = "security"
+ password = "Azure123456@"
+}
+
+resource "null_resource" "set_env" {
+ depends_on = [azuread_service_principal.resource-server-1]
+
+ provisioner "local-exec" {
+ command = "/bin/bash set_identifier_uris.sh"
+ }
+}
diff --git a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/outputs.tf b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/outputs.tf
new file mode 100644
index 000000000..b985e3d70
--- /dev/null
+++ b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/outputs.tf
@@ -0,0 +1,42 @@
+output "TENANT_ID" {
+ value = data.azuread_client_config.current.tenant_id
+ description = "The tenant id."
+}
+
+output "CLIENT_1_CLIENT_ID" {
+ value = azuread_application.client-1.application_id
+ description = "The application id of web app."
+}
+
+output "RESOURCE_SERVER_1_CLIENT_ID" {
+ value = azuread_application.resource-server-1.application_id
+ description = "The application id of resource server 1."
+}
+
+output "RESOURCE_SERVER_2_CLIENT_ID" {
+ value = azuread_application.resource-server-2.application_id
+ description = "The application id of resource server 2."
+}
+
+output "CLIENT_1_CLIENT_SECRET" {
+ value = azuread_application_password.client-1.value
+ sensitive = true
+ description = "The client secret of web app."
+}
+
+output "RESOURCE_SERVER_1_CLIENT_SECRET" {
+ value = azuread_application_password.resource-server-1.value
+ sensitive = true
+ description = "The client secret of resource server 1."
+}
+
+output "USER_NAME" {
+ value = azuread_user.user.user_principal_name
+ description = "The user name of the user created by terraform."
+}
+
+output "USER_PASSWORD" {
+ value = azuread_user.user.password
+ sensitive = true
+ description = "The password of the user created by terraform."
+}
diff --git a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/set_identifier_uris.sh b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/set_identifier_uris.sh
new file mode 100644
index 000000000..9510b7167
--- /dev/null
+++ b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/set_identifier_uris.sh
@@ -0,0 +1,11 @@
+RESOURCE_SERVER_1_CLIENT_ID=$(terraform output -raw RESOURCE_SERVER_1_CLIENT_ID)
+RESOURCE_SERVER_2_CLIENT_ID=$(terraform output -raw RESOURCE_SERVER_2_CLIENT_ID)
+
+# set identifier_uris
+echo "----------update identifier-uris for RESOURCE_SERVER_1----------"
+az ad app update --id $RESOURCE_SERVER_1_CLIENT_ID --identifier-uris api://$RESOURCE_SERVER_1_CLIENT_ID
+
+echo "----------update identifier-uris for RESOURCE_SERVER_2----------"
+az ad app update --id $RESOURCE_SERVER_2_CLIENT_ID --identifier-uris api://$RESOURCE_SERVER_2_CLIENT_ID
+
+echo "----------update identifier-uris completed----------"
diff --git a/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/setup_env.sh b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/setup_env.sh
new file mode 100644
index 000000000..c91569d95
--- /dev/null
+++ b/aad/spring-security/reactive/webflux/oauth2/spring-cloud-gateway/terraform/setup_env.sh
@@ -0,0 +1,20 @@
+export TENANT_ID=$(terraform -chdir=./terraform output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_ID)
+export RESOURCE_SERVER_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_1_CLIENT_ID)
+export RESOURCE_SERVER_2_CLIENT_ID=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_2_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_SECRET)
+export RESOURCE_SERVER_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_1_CLIENT_SECRET)
+export USER_NAME=$(terraform -chdir=./terraform output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=./terraform output -raw USER_PASSWORD)
+
+echo TENANT_ID=$TENANT_ID
+echo CLIENT_1_CLIENT_ID=$CLIENT_1_CLIENT_ID
+echo RESOURCE_SERVER_1_CLIENT_ID=$RESOURCE_SERVER_1_CLIENT_ID
+echo RESOURCE_SERVER_2_CLIENT_ID=$RESOURCE_SERVER_2_CLIENT_ID
+echo CLIENT_1_CLIENT_SECRET=$CLIENT_1_CLIENT_SECRET
+echo RESOURCE_SERVER_1_CLIENT_SECRET=$RESOURCE_SERVER_1_CLIENT_SECRET
+
+echo "--------created user--------"
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+
diff --git a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/README.md b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/README.md
new file mode 100644
index 000000000..15a77124a
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/README.md
@@ -0,0 +1,103 @@
+# Spring Boot application with Azure Active Directory
+
+## What You Need
+
+- [An Azure subscription](https://azure.microsoft.com/free/)
+- [Terraform](https://www.terraform.io/)
+- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
+- [JDK8](https://www.oracle.com/java/technologies/downloads/) or later
+- Maven
+- You can also import the code straight into your IDE:
+ - [IntelliJ IDEA](https://www.jetbrains.com/idea/download)
+
+## Provision Azure Resources Required to Run This Sample
+
+### Authenticate Using the Azure CLI
+Terraform must authenticate to Azure to create infrastructure.
+
+In your terminal, use the Azure CLI tool to setup your account permissions locally.
+
+```shell
+az login --tenant [your-tenant] --allow-no-subscriptions
+```
+
+Your browser window will open and you will be prompted to enter your Azure login credentials. After successful authentication, your terminal will display your subscription information. You do not need to save this output as it is saved in your system for Terraform to use.
+
+```shell
+You have logged in. Now let us find all the subscriptions to which you have access...
+
+[
+ {
+ "cloudName": "AzureCloud",
+ "homeTenantId": "home-Tenant-Id",
+ "id": "subscription-id",
+ "isDefault": true,
+ "managedByTenants": [],
+ "name": "Subscription-Name",
+ "state": "Enabled",
+ "tenantId": "0envbwi39-TenantId",
+ "user": {
+ "name": "your-username@domain.com",
+ "type": "user"
+ }
+ }
+]
+```
+
+### Provision the Resources
+
+After login Azure CLI with your account, now you can use the terraform script to create Azure Resources.
+
+#### Run with Bash
+
+```shell
+# Into the directory of client-access-multiple-resource-server
+# Initialize your Terraform configuration
+terraform -chdir=./terraform init
+
+# Apply your Terraform Configuration
+terraform -chdir=./terraform apply -auto-approve
+
+```
+
+It may take a few minutes to run the script. After successful running, you will see prompt information like below:
+
+```shell
+...
+Apply complete! Resources: * added, * changed, * destroyed.
+
+```
+
+You can go to [Azure portal](https://ms.portal.azure.com/) in your web browser to check the resources you created.
+
+### Export Output to Your Local Environment
+Running the command below to export environment values:
+
+#### Run with Bash
+
+```shell
+source ./terraform/setup_env.sh
+```
+
+## Run Locally
+
+In your current terminal, run `source run_all.sh`.
+
+```shell
+source run_all.sh
+```
+
+## Verify This Sample
+
+
+## Clean Up Resources
+After running the sample, if you don't want to run the sample, remember to destroy the Azure resources you created to avoid unnecessary billing.
+
+The terraform destroy command terminates resources managed by your Terraform project.
+To destroy the resources you created.
+
+#### Run with Bash
+
+```shell
+terraform -chdir=./terraform destroy -auto-approve
+```
diff --git a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/client/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/client/src/main/resources/application.yml
index 0fdb69b9f..1ab9538d3 100644
--- a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/client/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/client/src/main/resources/application.yml
@@ -1,9 +1,9 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${client-1-client-id}
-# 3. ${client-1-client-secret}
-# 4. ${resource-server-1-client-id}
-# 5. ${resource-server-2-client-id}
+# 1. ${TENANT_ID}
+# 2. ${CLIENT_1_CLIENT_ID}
+# 3. ${CLIENT_1_CLIENT_SECRET}
+# 4. ${RESOURCE_SERVER_1_CLIENT_ID}
+# 5. ${RESOURCE_SERVER_2_CLIENT_ID}
logging:
level:
@@ -16,22 +16,22 @@ spring:
client:
provider: # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login-common-oauth2-provider
azure-active-directory:
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
user-name-attribute: name
registration:
client-1-resource-server-1:
provider: azure-active-directory
client-name: client-1-resource-server-1
- client-id: ${client-1-client-id}
- client-secret: ${client-1-client-secret}
- scope: openid, profile, api://${resource-server-1-client-id}/resource-server-1.scope-1 # Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
+ client-id: ${CLIENT_1_CLIENT_ID}
+ client-secret: ${CLIENT_1_CLIENT_SECRET}
+ scope: openid, profile, api://${RESOURCE_SERVER_1_CLIENT_ID}/resource-server-1.scope-1 # Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
redirect-uri: http://localhost:8080/login/oauth2/code/
client-1-resource-server-2:
provider: azure-active-directory
client-name: client-1-resource-server-2
- client-id: ${client-1-client-id}
- client-secret: ${client-1-client-secret}
- scope: openid, profile, api://${resource-server-2-client-id}/resource-server-2.scope-1 # Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
+ client-id: ${CLIENT_1_CLIENT_ID}
+ client-secret: ${CLIENT_1_CLIENT_SECRET}
+ scope: openid, profile, api://${RESOURCE_SERVER_2_CLIENT_ID}/resource-server-2.scope-1 # Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
redirect-uri: http://localhost:8080/login/oauth2/code/
profiles:
active: develop
diff --git a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/resource-server-1/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/resource-server-1/src/main/resources/application.yml
index 6ce0ddb6c..611491f16 100644
--- a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/resource-server-1/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/resource-server-1/src/main/resources/application.yml
@@ -1,6 +1,6 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${resource-server-1-client-id}
+# 1. ${TENANT_ID}
+# 2. ${RESOURCE_SERVER_1_CLIENT_ID}
logging:
level:
@@ -12,6 +12,6 @@ spring:
oauth2:
resourceserver:
jwt:
- jwk-set-uri: https://login.microsoftonline.com/${tenant-id}/discovery/v2.0/keys
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0
- audience: ${resource-server-1-client-id}
+ jwk-set-uri: https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0
+ audience: ${RESOURCE_SERVER_1_CLIENT_ID}
diff --git a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/resource-server-2/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/resource-server-2/src/main/resources/application.yml
index 33386397e..0f4c1cb8f 100644
--- a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/resource-server-2/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/resource-server-2/src/main/resources/application.yml
@@ -1,6 +1,6 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${resource-server-2-client-id}
+# 1. ${TENANT_ID}
+# 2. ${RESOURCE_SERVER_2_CLIENT_ID}
logging:
level:
@@ -12,6 +12,6 @@ spring:
oauth2:
resourceserver:
jwt:
- jwk-set-uri: https://login.microsoftonline.com/${tenant-id}/discovery/v2.0/keys
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0
- audience: ${resource-server-2-client-id}
+ jwk-set-uri: https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0
+ audience: ${RESOURCE_SERVER_2_CLIENT_ID}
diff --git a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/run_all.sh b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/run_all.sh
new file mode 100644
index 000000000..0519acf63
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/run_all.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+
+kill -9 $(lsof -t -i tcp:8080)
+kill -9 $(lsof -t -i tcp:8081)
+kill -9 $(lsof -t -i tcp:8082)
+
+mvn clean package spring-boot:repackage -DskipTests -f ../../../pom.xml -pl com.azure.spring:servlet-oauth2-client-access-multiple-resource-server-client-application,\
+com.azure.spring:servlet-oauth2-client-access-multiple-resource-server-resource-server-1-application,\
+com.azure.spring:servlet-oauth2-client-access-multiple-resource-server-resource-server-2-application
+
+export terraform_path="./terraform"
+
+export TENANT_ID=$(terraform -chdir=$terraform_path output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw CLIENT_1_CLIENT_ID)
+export RESOURCE_SERVER_1_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_1_CLIENT_ID)
+export RESOURCE_SERVER_2_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_2_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=$terraform_path output -raw CLIENT_1_CLIENT_SECRET)
+export RESOURCE_SERVER_1_CLIENT_SECRET=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_1_CLIENT_SECRET)
+export USER_NAME=$(terraform -chdir=$terraform_path output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=$terraform_path output -raw USER_PASSWORD)
+
+
+echo "--------Running apps--------"
+mkdir -p target
+sleep 3
+echo "--------Running client--------"
+nohup java -jar client/target/*.jar > target/client.log 2>&1 &
+sleep 3
+echo "--------resource-server-1--------"
+nohup java -jar resource-server-1/target/*.jar > target/resource-server-1.log 2>&1 &
+sleep 3
+echo "--------resource-server-2--------"
+nohup java -jar resource-server-2/target/*.jar > target/resource-server-2.log 2>&1 &
+sleep 3
+echo "All apps started, please check target folder for logs."
+echo "You can use the user info below to login."
+echo "--------created user--------"
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+echo "Now you should be able to open browser to access http://localhost:8080 with user above."
+echo "If you encounter some errors, please refer to target folder for app logs ."
diff --git a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/main.tf b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/main.tf
new file mode 100644
index 000000000..d7b683eef
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/main.tf
@@ -0,0 +1,247 @@
+terraform {
+ required_providers {
+ azuread = {
+ source = "hashicorp/azuread"
+ version = "2.19.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "3.1.0"
+ }
+ null = {
+ source = "hashicorp/null"
+ version = "3.1.0"
+ }
+ }
+}
+
+resource "random_string" "random" {
+ length = 5
+ min_lower = 5
+ special = false
+}
+
+resource "random_uuid" "resource-server-1-scope-1" {
+}
+
+resource "random_uuid" "resource-server-1-scope-2" {
+}
+
+resource "random_uuid" "resource-server-2-scope-1" {
+}
+
+resource "random_uuid" "resource-server-2-scope-2" {
+}
+
+resource "random_uuid" "resource-server-1-role-1" {
+}
+
+resource "random_uuid" "resource-server-1-role-2" {
+}
+
+data "azuread_client_config" "current" {}
+
+# Configure the Azure Active Directory Provider
+provider "azuread" {
+}
+
+# Configure client-1
+resource "azuread_application" "client-1" {
+ display_name = "client-1-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/",
+ "http://localhost:8080/login/oauth2/code/client-1-resource-server-1",
+ "http://localhost:8080/login/oauth2/code/client-1-resource-server-2"]
+
+ implicit_grant {
+ access_token_issuance_enabled = true
+ id_token_issuance_enabled = true
+ }
+ }
+}
+
+
+# Configure resource-server-2
+resource "azuread_application" "resource-server-2" {
+ display_name = "resource-server-2-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-2.scope-1"
+ admin_consent_display_name = "resource-server-2.scope-1"
+ enabled = true
+ id = random_uuid.resource-server-2-scope-1.result
+ type = "User"
+ value = "resource-server-2.scope-1"
+ }
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-2.scope-2"
+ admin_consent_display_name = "resource-server-2.scope-2"
+ enabled = true
+ id = random_uuid.resource-server-2-scope-2.result
+ type = "User"
+ value = "resource-server-2.scope-2"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+}
+
+
+# Configure resource-server-1
+resource "azuread_application" "resource-server-1" {
+ display_name = "resource-server-1-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-1.scope-1"
+ admin_consent_display_name = "resource-server-1.scope-1"
+ enabled = true
+ id = random_uuid.resource-server-1-scope-1.result
+ type = "User"
+ value = "resource-server-1.scope-1"
+ }
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-1.scope-2"
+ admin_consent_display_name = "resource-server-1.scope-2"
+ enabled = true
+ id = random_uuid.resource-server-1-scope-2.result
+ type = "User"
+ value = "resource-server-1.scope-2"
+ }
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "resource-server-1-role-2"
+ display_name = "resource-server-1-role-2"
+ enabled = true
+ id = random_uuid.resource-server-1-role-2.result
+ value = "resource-server-1-role-2"
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "resource-server-1-role-1"
+ display_name = "resource-server-1-role-1"
+ enabled = true
+ id = random_uuid.resource-server-1-role-1.result
+ value = "resource-server-1-role-1"
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = azuread_application.resource-server-2.application_id # Resource server 2
+
+ # need grant
+ resource_access {
+ id = random_uuid.resource-server-2-scope-1.result # resource-server-2.scope-1
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/"]
+ }
+}
+
+resource "azuread_service_principal_delegated_permission_grant" "resource-server-1" {
+ service_principal_object_id = azuread_service_principal.resource-server-1.object_id
+ resource_service_principal_object_id = azuread_service_principal.resource-server-2.object_id
+ claim_values = ["resource-server-2.scope-1"]
+}
+
+resource "azuread_service_principal" "client-1" {
+ application_id = azuread_application.client-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_service_principal" "resource-server-1" {
+ application_id = azuread_application.resource-server-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_service_principal" "resource-server-2" {
+ application_id = azuread_application.resource-server-2.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+
+resource "azuread_application_password" "client-1" {
+ application_object_id = azuread_application.client-1.object_id
+}
+
+
+resource "azuread_application_password" "resource-server-1" {
+ application_object_id = azuread_application.resource-server-1.object_id
+}
+
+# Retrieve domain information
+data "azuread_domains" "example" {
+ only_initial = true
+}
+
+# Create a user
+resource "azuread_user" "user" {
+ user_principal_name = "security-${random_string.random.result}@${data.azuread_domains.example.domains.0.domain_name}"
+ display_name = "security"
+ password = "Azure123456@"
+}
+
+resource "null_resource" "set_env" {
+ depends_on = [azuread_service_principal.resource-server-1]
+
+ provisioner "local-exec" {
+ command = "/bin/bash set_identifier_uris.sh"
+ }
+}
diff --git a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/outputs.tf b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/outputs.tf
new file mode 100644
index 000000000..b985e3d70
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/outputs.tf
@@ -0,0 +1,42 @@
+output "TENANT_ID" {
+ value = data.azuread_client_config.current.tenant_id
+ description = "The tenant id."
+}
+
+output "CLIENT_1_CLIENT_ID" {
+ value = azuread_application.client-1.application_id
+ description = "The application id of web app."
+}
+
+output "RESOURCE_SERVER_1_CLIENT_ID" {
+ value = azuread_application.resource-server-1.application_id
+ description = "The application id of resource server 1."
+}
+
+output "RESOURCE_SERVER_2_CLIENT_ID" {
+ value = azuread_application.resource-server-2.application_id
+ description = "The application id of resource server 2."
+}
+
+output "CLIENT_1_CLIENT_SECRET" {
+ value = azuread_application_password.client-1.value
+ sensitive = true
+ description = "The client secret of web app."
+}
+
+output "RESOURCE_SERVER_1_CLIENT_SECRET" {
+ value = azuread_application_password.resource-server-1.value
+ sensitive = true
+ description = "The client secret of resource server 1."
+}
+
+output "USER_NAME" {
+ value = azuread_user.user.user_principal_name
+ description = "The user name of the user created by terraform."
+}
+
+output "USER_PASSWORD" {
+ value = azuread_user.user.password
+ sensitive = true
+ description = "The password of the user created by terraform."
+}
diff --git a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/set_identifier_uris.sh b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/set_identifier_uris.sh
new file mode 100644
index 000000000..9510b7167
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/set_identifier_uris.sh
@@ -0,0 +1,11 @@
+RESOURCE_SERVER_1_CLIENT_ID=$(terraform output -raw RESOURCE_SERVER_1_CLIENT_ID)
+RESOURCE_SERVER_2_CLIENT_ID=$(terraform output -raw RESOURCE_SERVER_2_CLIENT_ID)
+
+# set identifier_uris
+echo "----------update identifier-uris for RESOURCE_SERVER_1----------"
+az ad app update --id $RESOURCE_SERVER_1_CLIENT_ID --identifier-uris api://$RESOURCE_SERVER_1_CLIENT_ID
+
+echo "----------update identifier-uris for RESOURCE_SERVER_2----------"
+az ad app update --id $RESOURCE_SERVER_2_CLIENT_ID --identifier-uris api://$RESOURCE_SERVER_2_CLIENT_ID
+
+echo "----------update identifier-uris completed----------"
diff --git a/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/setup_env.sh b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/setup_env.sh
new file mode 100644
index 000000000..c91569d95
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-multiple-resource-server/terraform/setup_env.sh
@@ -0,0 +1,20 @@
+export TENANT_ID=$(terraform -chdir=./terraform output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_ID)
+export RESOURCE_SERVER_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_1_CLIENT_ID)
+export RESOURCE_SERVER_2_CLIENT_ID=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_2_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_SECRET)
+export RESOURCE_SERVER_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_1_CLIENT_SECRET)
+export USER_NAME=$(terraform -chdir=./terraform output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=./terraform output -raw USER_PASSWORD)
+
+echo TENANT_ID=$TENANT_ID
+echo CLIENT_1_CLIENT_ID=$CLIENT_1_CLIENT_ID
+echo RESOURCE_SERVER_1_CLIENT_ID=$RESOURCE_SERVER_1_CLIENT_ID
+echo RESOURCE_SERVER_2_CLIENT_ID=$RESOURCE_SERVER_2_CLIENT_ID
+echo CLIENT_1_CLIENT_SECRET=$CLIENT_1_CLIENT_SECRET
+echo RESOURCE_SERVER_1_CLIENT_SECRET=$RESOURCE_SERVER_1_CLIENT_SECRET
+
+echo "--------created user--------"
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+
diff --git a/aad/spring-security/servlet/oauth2/client-access-resource-server/README.md b/aad/spring-security/servlet/oauth2/client-access-resource-server/README.md
new file mode 100644
index 000000000..d5d5b2ede
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-resource-server/README.md
@@ -0,0 +1,103 @@
+# Spring Boot application with Azure Active Directory
+
+## What You Need
+
+- [An Azure subscription](https://azure.microsoft.com/free/)
+- [Terraform](https://www.terraform.io/)
+- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
+- [JDK8](https://www.oracle.com/java/technologies/downloads/) or later
+- Maven
+- You can also import the code straight into your IDE:
+ - [IntelliJ IDEA](https://www.jetbrains.com/idea/download)
+
+## Provision Azure Resources Required to Run This Sample
+
+### Authenticate Using the Azure CLI
+Terraform must authenticate to Azure to create infrastructure.
+
+In your terminal, use the Azure CLI tool to setup your account permissions locally.
+
+```shell
+az login --tenant [your-tenant] --allow-no-subscriptions
+```
+
+Your browser window will open and you will be prompted to enter your Azure login credentials. After successful authentication, your terminal will display your subscription information. You do not need to save this output as it is saved in your system for Terraform to use.
+
+```shell
+You have logged in. Now let us find all the subscriptions to which you have access...
+
+[
+ {
+ "cloudName": "AzureCloud",
+ "homeTenantId": "home-Tenant-Id",
+ "id": "subscription-id",
+ "isDefault": true,
+ "managedByTenants": [],
+ "name": "Subscription-Name",
+ "state": "Enabled",
+ "tenantId": "0envbwi39-TenantId",
+ "user": {
+ "name": "your-username@domain.com",
+ "type": "user"
+ }
+ }
+]
+```
+
+### Provision the Resources
+
+After login Azure CLI with your account, now you can use the terraform script to create Azure Resources.
+
+#### Run with Bash
+
+```shell
+# Into the directory of client-access-resource-server
+# Initialize your Terraform configuration
+terraform -chdir=./terraform init
+
+# Apply your Terraform Configuration
+terraform -chdir=./terraform apply -auto-approve
+
+```
+
+It may take a few minutes to run the script. After successful running, you will see prompt information like below:
+
+```shell
+...
+Apply complete! Resources: * added, * changed, * destroyed.
+
+```
+
+You can go to [Azure portal](https://ms.portal.azure.com/) in your web browser to check the resources you created.
+
+### Export Output to Your Local Environment
+Running the command below to export environment values:
+
+#### Run with Bash
+
+```shell
+source ./terraform/setup_env.sh
+```
+
+## Run Locally
+
+In your current terminal, run `source run_all.sh`.
+
+```shell
+source run_all.sh
+```
+
+## Verify This Sample
+
+
+## Clean Up Resources
+After running the sample, if you don't want to run the sample, remember to destroy the Azure resources you created to avoid unnecessary billing.
+
+The terraform destroy command terminates resources managed by your Terraform project.
+To destroy the resources you created.
+
+#### Run with Bash
+
+```shell
+terraform -chdir=./terraform destroy -auto-approve
+```
diff --git a/aad/spring-security/servlet/oauth2/client-access-resource-server/client/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/client-access-resource-server/client/src/main/resources/application.yml
index 103320817..4ae27bfdd 100644
--- a/aad/spring-security/servlet/oauth2/client-access-resource-server/client/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/client-access-resource-server/client/src/main/resources/application.yml
@@ -1,8 +1,8 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${client-1-client-id}
-# 3. ${client-1-client-secret}
-# 4. ${resource-server-1-client-id}
+# 1. ${TENANT_ID}
+# 2. ${CLIENT_1_CLIENT_ID}
+# 3. ${CLIENT_1_CLIENT_SECRET}
+# 4. ${RESOURCE_SERVER_1_CLIENT_ID}
logging:
level:
@@ -15,12 +15,12 @@ spring:
client:
provider: # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login-common-oauth2-provider
azure-active-directory:
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
user-name-attribute: name
registration:
client-1-resource-server-1:
provider: azure-active-directory
- client-id: ${client-1-client-id}
- client-secret: ${client-1-client-secret}
- scope: openid, profile, offline_access, api://${resource-server-1-client-id}/resource-server-1.scope-1, # Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
+ client-id: ${CLIENT_1_CLIENT_ID}
+ client-secret: ${CLIENT_1_CLIENT_SECRET}
+ scope: openid, profile, offline_access, api://${RESOURCE_SERVER_1_CLIENT_ID}/resource-server-1.scope-1, # Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
redirect-uri: http://localhost:8080/login/oauth2/code/
diff --git a/aad/spring-security/servlet/oauth2/client-access-resource-server/resource-server/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/client-access-resource-server/resource-server/src/main/resources/application.yml
index 6ce0ddb6c..611491f16 100644
--- a/aad/spring-security/servlet/oauth2/client-access-resource-server/resource-server/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/client-access-resource-server/resource-server/src/main/resources/application.yml
@@ -1,6 +1,6 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${resource-server-1-client-id}
+# 1. ${TENANT_ID}
+# 2. ${RESOURCE_SERVER_1_CLIENT_ID}
logging:
level:
@@ -12,6 +12,6 @@ spring:
oauth2:
resourceserver:
jwt:
- jwk-set-uri: https://login.microsoftonline.com/${tenant-id}/discovery/v2.0/keys
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0
- audience: ${resource-server-1-client-id}
+ jwk-set-uri: https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0
+ audience: ${RESOURCE_SERVER_1_CLIENT_ID}
diff --git a/aad/spring-security/servlet/oauth2/client-access-resource-server/run_all.sh b/aad/spring-security/servlet/oauth2/client-access-resource-server/run_all.sh
new file mode 100644
index 000000000..7883e264a
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-resource-server/run_all.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+kill -9 $(lsof -t -i tcp:8080)
+kill -9 $(lsof -t -i tcp:8081)
+
+mvn clean package spring-boot:repackage -DskipTests -f ../../../pom.xml -pl \
+com.azure.spring:servlet-oauth2-client-access-resource-server-client-application,\
+com.azure.spring:servlet-oauth2-client-access-resource-server-resource-server-application
+
+export terraform_path="./terraform"
+
+export TENANT_ID=$(terraform -chdir=$terraform_path output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw CLIENT_1_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=$terraform_path output -raw CLIENT_1_CLIENT_SECRET)
+export RESOURCE_SERVER_1_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_1_CLIENT_ID)
+
+export USER_NAME=$(terraform -chdir=$terraform_path output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=$terraform_path output -raw USER_PASSWORD)
+
+echo "Running apps"
+mkdir -p target
+echo "Running app client---------"
+nohup java -jar client/target/*.jar > target/client.log 2>&1 &
+echo "Running resource-server ---------"
+nohup java -jar resource-server/target/*.jar > target/resource-server-1.log 2>&1 &
+sleep 10
+
+echo "All apps started, please check target folder for logs."
+echo "You can use the user info below to login."
+echo "--------created user--------"
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+echo "Now you should be able to open browser to access http://localhost:8080 with user above."
+echo "If you encounter some errors, please refer to target folder for app logs ."
diff --git a/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/main.tf b/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/main.tf
new file mode 100644
index 000000000..1b49147a4
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/main.tf
@@ -0,0 +1,178 @@
+terraform {
+ required_providers {
+ azuread = {
+ source = "hashicorp/azuread"
+ version = "2.19.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "3.1.0"
+ }
+ null = {
+ source = "hashicorp/null"
+ version = "3.1.0"
+ }
+ }
+}
+
+resource "random_string" "random" {
+ length = 5
+ min_lower = 5
+ special = false
+}
+
+resource "random_uuid" "resource-server-1-scope-1" {
+}
+
+resource "random_uuid" "resource-server-1-scope-2" {
+}
+
+resource "random_uuid" "resource-server-1-role-1" {
+}
+
+resource "random_uuid" "resource-server-1-role-2" {
+}
+
+data "azuread_client_config" "current" {}
+
+# Configure the Azure Active Directory Provider
+provider "azuread" {
+}
+
+# Configure client-1
+resource "azuread_application" "client-1" {
+ display_name = "client-1-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/",
+ "http://localhost:8080/login/oauth2/code/client-1-resource-server-1",
+ "http://localhost:8080/login/oauth2/code/client-1-resource-server-2"]
+
+ implicit_grant {
+ access_token_issuance_enabled = true
+ id_token_issuance_enabled = true
+ }
+ }
+}
+
+
+
+# Configure resource-server-1
+resource "azuread_application" "resource-server-1" {
+ display_name = "resource-server-1-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-1.scope-1"
+ admin_consent_display_name = "resource-server-1.scope-1"
+ enabled = true
+ id = random_uuid.resource-server-1-scope-1.result
+ type = "User"
+ value = "resource-server-1.scope-1"
+ }
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-1.scope-2"
+ admin_consent_display_name = "resource-server-1.scope-2"
+ enabled = true
+ id = random_uuid.resource-server-1-scope-2.result
+ type = "User"
+ value = "resource-server-1.scope-2"
+ }
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "resource-server-1-role-2"
+ display_name = "resource-server-1-role-2"
+ enabled = true
+ id = random_uuid.resource-server-1-role-2.result
+ value = "resource-server-1-role-2"
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "resource-server-1-role-1"
+ display_name = "resource-server-1-role-1"
+ enabled = true
+ id = random_uuid.resource-server-1-role-1.result
+ value = "resource-server-1-role-1"
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/"]
+ }
+}
+
+resource "azuread_service_principal" "client-1" {
+ application_id = azuread_application.client-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_service_principal" "resource-server-1" {
+ application_id = azuread_application.resource-server-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_application_password" "client-1" {
+ application_object_id = azuread_application.client-1.object_id
+}
+
+
+resource "azuread_application_password" "resource-server-1" {
+ application_object_id = azuread_application.resource-server-1.object_id
+}
+
+# Retrieve domain information
+data "azuread_domains" "example" {
+ only_initial = true
+}
+
+# Create a user
+resource "azuread_user" "user" {
+ user_principal_name = "security-${random_string.random.result}@${data.azuread_domains.example.domains.0.domain_name}"
+ display_name = "security"
+ password = "Azure123456@"
+}
+
+resource "null_resource" "set_env" {
+ depends_on = [azuread_service_principal.resource-server-1]
+
+ provisioner "local-exec" {
+ command = "/bin/bash set_identifier_uris.sh"
+ }
+}
diff --git a/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/outputs.tf b/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/outputs.tf
new file mode 100644
index 000000000..64a2a45b7
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/outputs.tf
@@ -0,0 +1,37 @@
+output "TENANT_ID" {
+ value = data.azuread_client_config.current.tenant_id
+ description = "The tenant id."
+}
+
+output "CLIENT_1_CLIENT_ID" {
+ value = azuread_application.client-1.application_id
+ description = "The application id of web app."
+}
+
+output "RESOURCE_SERVER_1_CLIENT_ID" {
+ value = azuread_application.resource-server-1.application_id
+ description = "The application id of resource server 1."
+}
+
+output "CLIENT_1_CLIENT_SECRET" {
+ value = azuread_application_password.client-1.value
+ sensitive = true
+ description = "The client secret of web app."
+}
+
+output "RESOURCE_SERVER_1_CLIENT_SECRET" {
+ value = azuread_application_password.resource-server-1.value
+ sensitive = true
+ description = "The client secret of resource server 1."
+}
+
+output "USER_NAME" {
+ value = azuread_user.user.user_principal_name
+ description = "The user name of the user created by terraform."
+}
+
+output "USER_PASSWORD" {
+ value = azuread_user.user.password
+ sensitive = true
+ description = "The password of the user created by terraform."
+}
diff --git a/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/set_identifier_uris.sh b/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/set_identifier_uris.sh
new file mode 100644
index 000000000..b316f5d50
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/set_identifier_uris.sh
@@ -0,0 +1,7 @@
+RESOURCE_SERVER_1_CLIENT_ID=$(terraform output -raw RESOURCE_SERVER_1_CLIENT_ID)
+
+# set identifier_uris
+echo "----------update identifier-uris for RESOURCE_SERVER_1----------"
+az ad app update --id $RESOURCE_SERVER_1_CLIENT_ID --identifier-uris api://$RESOURCE_SERVER_1_CLIENT_ID
+
+echo "----------update identifier-uris completed----------"
diff --git a/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/setup_env.sh b/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/setup_env.sh
new file mode 100644
index 000000000..926eb7c26
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/client-access-resource-server/terraform/setup_env.sh
@@ -0,0 +1,19 @@
+export TENANT_ID=$(terraform -chdir=./terraform output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_ID)
+export RESOURCE_SERVER_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_1_CLIENT_ID)
+export RESOURCE_SERVER_2_CLIENT_ID=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_2_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_SECRET)
+export RESOURCE_SERVER_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_1_CLIENT_SECRET)
+export USER_NAME=$(terraform -chdir=./terraform output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=./terraform output -raw USER_PASSWORD)
+
+echo TENANT_ID=$TENANT_ID
+echo CLIENT_1_CLIENT_ID=$CLIENT_1_CLIENT_ID
+echo RESOURCE_SERVER_1_CLIENT_ID=$RESOURCE_SERVER_1_CLIENT_ID
+echo RESOURCE_SERVER_2_CLIENT_ID=$RESOURCE_SERVER_2_CLIENT_ID
+echo CLIENT_1_CLIENT_SECRET=$CLIENT_1_CLIENT_SECRET
+echo RESOURCE_SERVER_1_CLIENT_SECRET=$RESOURCE_SERVER_1_CLIENT_SECRET
+echo "--------created user--------"
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+
diff --git a/aad/spring-security/servlet/oauth2/login/README.md b/aad/spring-security/servlet/oauth2/login/README.md
new file mode 100644
index 000000000..dccdee41b
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/login/README.md
@@ -0,0 +1,113 @@
+# Spring Boot application with Azure Active Directory
+
+## What You Need
+
+- [An Azure subscription](https://azure.microsoft.com/free/)
+- [Terraform](https://www.terraform.io/)
+- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
+- [JDK8](https://www.oracle.com/java/technologies/downloads/) or later
+- Maven
+- You can also import the code straight into your IDE:
+ - [IntelliJ IDEA](https://www.jetbrains.com/idea/download)
+
+## Provision Azure Resources Required to Run This Sample
+
+### Authenticate Using the Azure CLI
+Terraform must authenticate to Azure to create infrastructure.
+
+In your terminal, use the Azure CLI tool to setup your account permissions locally.
+
+```shell
+az login --tenant [your-tenant] --allow-no-subscriptions
+```
+
+Your browser window will open and you will be prompted to enter your Azure login credentials. After successful authentication, your terminal will display your subscription information. You do not need to save this output as it is saved in your system for Terraform to use.
+
+```shell
+You have logged in. Now let us find all the subscriptions to which you have access...
+
+[
+ {
+ "cloudName": "AzureCloud",
+ "homeTenantId": "home-Tenant-Id",
+ "id": "subscription-id",
+ "isDefault": true,
+ "managedByTenants": [],
+ "name": "Subscription-Name",
+ "state": "Enabled",
+ "tenantId": "0envbwi39-TenantId",
+ "user": {
+ "name": "your-username@domain.com",
+ "type": "user"
+ }
+ }
+]
+```
+
+### Provision the Resources
+
+After login Azure CLI with your account, now you can use the terraform script to create Azure Resources.
+
+#### Run with Bash
+
+```shell
+# Into the directory of login
+# Initialize your Terraform configuration
+terraform -chdir=./terraform init
+
+# Apply your Terraform Configuration
+terraform -chdir=./terraform apply -auto-approve
+
+```
+
+It may take a few minutes to run the script. After successful running, you will see prompt information like below:
+
+```shell
+...
+Apply complete! Resources: * added, * changed, * destroyed.
+
+```
+
+You can go to [Azure portal](https://ms.portal.azure.com/) in your web browser to check the resources you created.
+
+### Export Output to Your Local Environment
+Running the command below to export environment values:
+
+#### Run with Bash
+
+```shell
+source ./terraform/setup_env.sh
+```
+
+You will see output like below, save this output of `created user` to login.
+```shell
+TENANT_ID=...
+CLIENT_1_CLIENT_ID=...
+CLIENT_1_CLIENT_SECRET=...
+--------created user--------
+USER_NAME=...
+USER_PASSWORD=...
+
+```
+
+## Run Locally
+
+In your current terminal, run `mvn clean spring-boot:run`.
+
+```shell
+mvn clean spring-boot:run
+```
+## Verify This Sample
+
+
+## Clean Up Resources
+After running the sample, if you don't want to run the sample, remember to destroy the Azure resources you created to avoid unnecessary billing.
+
+The terraform destroy command terminates resources managed by your Terraform project.
+To destroy the resources you created.
+
+#### Run with Bash
+
+```shell
+terraform -chdir=./terraform destroy -auto-approve
+```
diff --git a/aad/spring-security/servlet/oauth2/login/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/login/src/main/resources/application.yml
index a5fbd2990..5aa0065ed 100644
--- a/aad/spring-security/servlet/oauth2/login/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/login/src/main/resources/application.yml
@@ -1,7 +1,7 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${client-1-client-id}
-# 3. ${client-1-client-secret}
+# 1. ${TENANT_ID}
+# 2. ${CLIENT_1_CLIENT_ID}
+# 3. ${CLIENT_1_CLIENT_SECRET}
logging:
level:
@@ -14,12 +14,12 @@ spring:
client:
provider: # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login-common-oauth2-provider
azure-active-directory:
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
registration:
client-1:
provider: azure-active-directory
- client-id: ${client-1-client-id}
- client-secret: ${client-1-client-secret}
+ client-id: ${CLIENT_1_CLIENT_ID}
+ client-secret: ${CLIENT_1_CLIENT_SECRET}
scope: openid, profile
redirect-uri: http://localhost:8080/login/oauth2/code/
profiles:
diff --git a/aad/spring-security/servlet/oauth2/login/terraform/main.tf b/aad/spring-security/servlet/oauth2/login/terraform/main.tf
new file mode 100644
index 000000000..accb58345
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/login/terraform/main.tf
@@ -0,0 +1,76 @@
+terraform {
+ required_providers {
+ azuread = {
+ source = "hashicorp/azuread"
+ version = "2.19.0"
+ }
+ }
+}
+
+resource "random_string" "random" {
+ length = 5
+ min_lower = 5
+ special = false
+}
+
+data "azuread_client_config" "current" {}
+
+# Configure the Azure Active Directory Provider
+provider "azuread" {
+}
+
+# Configure client-1
+resource "azuread_application" "client-1" {
+ display_name = "client-1-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/"]
+
+ implicit_grant {
+ access_token_issuance_enabled = true
+ id_token_issuance_enabled = true
+ }
+ }
+}
+
+
+resource "azuread_service_principal" "client-1" {
+ application_id = azuread_application.client-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+
+resource "azuread_application_password" "client-1" {
+ application_object_id = azuread_application.client-1.object_id
+}
+
+
+# Retrieve domain information
+data "azuread_domains" "example" {
+ only_initial = true
+}
+
+# Create a user
+resource "azuread_user" "user" {
+ user_principal_name = "security-${random_string.random.result}@${data.azuread_domains.example.domains.0.domain_name}"
+ display_name = "security"
+ password = "Azure123456@"
+}
diff --git a/aad/spring-security/servlet/oauth2/login/terraform/outputs.tf b/aad/spring-security/servlet/oauth2/login/terraform/outputs.tf
new file mode 100644
index 000000000..85ae482fc
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/login/terraform/outputs.tf
@@ -0,0 +1,26 @@
+output "TENANT_ID" {
+ value = data.azuread_client_config.current.tenant_id
+ description = "The tenant id."
+}
+
+output "CLIENT_1_CLIENT_ID" {
+ value = azuread_application.client-1.application_id
+ description = "The application id of web app."
+}
+
+output "CLIENT_1_CLIENT_SECRET" {
+ value = azuread_application_password.client-1.value
+ sensitive = true
+ description = "The client secret of web app."
+}
+
+output "USER_NAME" {
+ value = azuread_user.user.user_principal_name
+ description = "The user name of the user created by terraform."
+}
+
+output "USER_PASSWORD" {
+ value = azuread_user.user.password
+ sensitive = true
+ description = "The password of the user created by terraform."
+}
diff --git a/aad/spring-security/servlet/oauth2/login/terraform/setup_env.sh b/aad/spring-security/servlet/oauth2/login/terraform/setup_env.sh
new file mode 100644
index 000000000..4b930b047
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/login/terraform/setup_env.sh
@@ -0,0 +1,14 @@
+export TENANT_ID=$(terraform -chdir=./terraform output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_SECRET)
+export USER_NAME=$(terraform -chdir=./terraform output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=./terraform output -raw USER_PASSWORD)
+
+echo TENANT_ID=$TENANT_ID
+echo CLIENT_1_CLIENT_ID=$CLIENT_1_CLIENT_ID
+echo CLIENT_1_CLIENT_SECRET=$CLIENT_1_CLIENT_SECRET
+
+echo "--------created user--------"
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+
diff --git a/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/README.md b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/README.md
new file mode 100644
index 000000000..b4796a3b5
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/README.md
@@ -0,0 +1,103 @@
+# Spring Boot application with Azure Active Directory
+
+## What You Need
+
+- [An Azure subscription](https://azure.microsoft.com/free/)
+- [Terraform](https://www.terraform.io/)
+- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
+- [JDK8](https://www.oracle.com/java/technologies/downloads/) or later
+- Maven
+- You can also import the code straight into your IDE:
+ - [IntelliJ IDEA](https://www.jetbrains.com/idea/download)
+
+## Provision Azure Resources Required to Run This Sample
+
+### Authenticate Using the Azure CLI
+Terraform must authenticate to Azure to create infrastructure.
+
+In your terminal, use the Azure CLI tool to setup your account permissions locally.
+
+```shell
+az login --tenant [your-tenant] --allow-no-subscriptions
+```
+
+Your browser window will open and you will be prompted to enter your Azure login credentials. After successful authentication, your terminal will display your subscription information. You do not need to save this output as it is saved in your system for Terraform to use.
+
+```shell
+You have logged in. Now let us find all the subscriptions to which you have access...
+
+[
+ {
+ "cloudName": "AzureCloud",
+ "homeTenantId": "home-Tenant-Id",
+ "id": "subscription-id",
+ "isDefault": true,
+ "managedByTenants": [],
+ "name": "Subscription-Name",
+ "state": "Enabled",
+ "tenantId": "0envbwi39-TenantId",
+ "user": {
+ "name": "your-username@domain.com",
+ "type": "user"
+ }
+ }
+]
+```
+
+### Provision the Resources
+
+After login Azure CLI with your account, now you can use the terraform script to create Azure Resources.
+
+#### Run with Bash
+
+```shell
+# Into the directory of resource-server-check-permissions-by-claims-in-access-token
+# Initialize your Terraform configuration
+terraform -chdir=./terraform init
+
+# Apply your Terraform Configuration
+terraform -chdir=./terraform apply -auto-approve
+
+```
+
+It may take a few minutes to run the script. After successful running, you will see prompt information like below:
+
+```shell
+...
+Apply complete! Resources: * added, * changed, * destroyed.
+
+```
+
+You can go to [Azure portal](https://ms.portal.azure.com/) in your web browser to check the resources you created.
+
+### Export Output to Your Local Environment
+Running the command below to export environment values:
+
+#### Run with Bash
+
+```shell
+source ./terraform/setup_env.sh
+```
+
+## Run Locally
+
+In your current terminal, run `source run_all.sh`.
+
+```shell
+source run_all.sh
+```
+
+## Verify This Sample
+
+
+## Clean Up Resources
+After running the sample, if you don't want to run the sample, remember to destroy the Azure resources you created to avoid unnecessary billing.
+
+The terraform destroy command terminates resources managed by your Terraform project.
+To destroy the resources you created.
+
+#### Run with Bash
+
+```shell
+terraform -chdir=./terraform destroy -auto-approve
+```
diff --git a/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/client/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/client/src/main/resources/application.yml
index 103320817..4ae27bfdd 100644
--- a/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/client/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/client/src/main/resources/application.yml
@@ -1,8 +1,8 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${client-1-client-id}
-# 3. ${client-1-client-secret}
-# 4. ${resource-server-1-client-id}
+# 1. ${TENANT_ID}
+# 2. ${CLIENT_1_CLIENT_ID}
+# 3. ${CLIENT_1_CLIENT_SECRET}
+# 4. ${RESOURCE_SERVER_1_CLIENT_ID}
logging:
level:
@@ -15,12 +15,12 @@ spring:
client:
provider: # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login-common-oauth2-provider
azure-active-directory:
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
user-name-attribute: name
registration:
client-1-resource-server-1:
provider: azure-active-directory
- client-id: ${client-1-client-id}
- client-secret: ${client-1-client-secret}
- scope: openid, profile, offline_access, api://${resource-server-1-client-id}/resource-server-1.scope-1, # Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
+ client-id: ${CLIENT_1_CLIENT_ID}
+ client-secret: ${CLIENT_1_CLIENT_SECRET}
+ scope: openid, profile, offline_access, api://${RESOURCE_SERVER_1_CLIENT_ID}/resource-server-1.scope-1, # Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
redirect-uri: http://localhost:8080/login/oauth2/code/
diff --git a/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/resource-server/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/resource-server/src/main/resources/application.yml
index 6ce0ddb6c..611491f16 100644
--- a/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/resource-server/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/resource-server/src/main/resources/application.yml
@@ -1,6 +1,6 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${resource-server-1-client-id}
+# 1. ${TENANT_ID}
+# 2. ${RESOURCE_SERVER_1_CLIENT_ID}
logging:
level:
@@ -12,6 +12,6 @@ spring:
oauth2:
resourceserver:
jwt:
- jwk-set-uri: https://login.microsoftonline.com/${tenant-id}/discovery/v2.0/keys
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0
- audience: ${resource-server-1-client-id}
+ jwk-set-uri: https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0
+ audience: ${RESOURCE_SERVER_1_CLIENT_ID}
diff --git a/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/run_all.sh b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/run_all.sh
new file mode 100644
index 000000000..5c2c7965f
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/run_all.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+kill -9 $(lsof -t -i tcp:8080)
+kill -9 $(lsof -t -i tcp:8081)
+
+mvn clean package spring-boot:repackage -DskipTests -f ../../../pom.xml -pl \
+com.azure.spring:servlet-oauth2-resource-server-check-permissions-by-claims-in-access-token-client-application,\
+com.azure.spring:servlet-oauth2-resource-server-check-permissions-by-claims-in-access-token-resource-server-application
+
+export terraform_path="./terraform"
+
+export TENANT_ID=$(terraform -chdir=$terraform_path output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw CLIENT_1_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=$terraform_path output -raw CLIENT_1_CLIENT_SECRET)
+export RESOURCE_SERVER_1_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_1_CLIENT_ID)
+
+echo "Running apps"
+mkdir -p target
+echo "Running client-----------"
+nohup java -jar client/target/*.jar > target/client.log 2>&1 &
+echo "Running resource-server-----------"
+nohup java -jar resource-server/target/*.jar > target/resource-server-1.log 2>&1 &
+sleep 10
+
+echo "All apps started, please check target folder for logs."
+echo "You can use the user info below to login."
+echo "--------created user--------"
+export USER_NAME=$(terraform -chdir=$terraform_path output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=$terraform_path output -raw USER_PASSWORD)
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+echo "Now you should be able to open browser to access http://localhost:8080 with user above."
+echo "If you encounter some errors, please refer to target folder for app logs ."
\ No newline at end of file
diff --git a/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/main.tf b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/main.tf
new file mode 100644
index 000000000..42bdec289
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/main.tf
@@ -0,0 +1,184 @@
+terraform {
+ required_providers {
+ azuread = {
+ source = "hashicorp/azuread"
+ version = "2.19.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "3.1.0"
+ }
+ null = {
+ source = "hashicorp/null"
+ version = "3.1.0"
+ }
+ }
+}
+
+resource "random_string" "random" {
+ length = 5
+ min_lower = 5
+ special = false
+}
+
+resource "random_uuid" "resource-server-1-scope-1" {
+}
+
+resource "random_uuid" "resource-server-1-scope-2" {
+}
+
+resource "random_uuid" "resource-server-1-role-1" {
+}
+
+resource "random_uuid" "resource-server-1-role-2" {
+}
+
+data "azuread_client_config" "current" {}
+
+# Configure the Azure Active Directory Provider
+provider "azuread" {
+}
+
+# Configure client-1
+resource "azuread_application" "client-1" {
+ display_name = "client-1-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/",
+ "http://localhost:8080/login/oauth2/code/client-1-resource-server-1",
+ "http://localhost:8080/login/oauth2/code/client-1-resource-server-2"]
+
+ implicit_grant {
+ access_token_issuance_enabled = true
+ id_token_issuance_enabled = true
+ }
+ }
+}
+
+
+# Configure resource-server-1
+resource "azuread_application" "resource-server-1" {
+ display_name = "resource-server-1-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-1.scope-1"
+ admin_consent_display_name = "resource-server-1.scope-1"
+ enabled = true
+ id = random_uuid.resource-server-1-scope-1.result
+ type = "User"
+ value = "resource-server-1.scope-1"
+ }
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-1.scope-2"
+ admin_consent_display_name = "resource-server-1.scope-2"
+ enabled = true
+ id = random_uuid.resource-server-1-scope-2.result
+ type = "User"
+ value = "resource-server-1.scope-2"
+ }
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "resource-server-1-role-2"
+ display_name = "resource-server-1-role-2"
+ enabled = true
+ id = random_uuid.resource-server-1-role-2.result
+ value = "resource-server-1-role-2"
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "resource-server-1-role-1"
+ display_name = "resource-server-1-role-1"
+ enabled = true
+ id = random_uuid.resource-server-1-role-1.result
+ value = "resource-server-1-role-1"
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/"]
+ }
+}
+
+resource "azuread_service_principal" "client-1" {
+ application_id = azuread_application.client-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_service_principal" "resource-server-1" {
+ application_id = azuread_application.resource-server-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+
+resource "azuread_application_password" "client-1" {
+ application_object_id = azuread_application.client-1.object_id
+}
+
+
+resource "azuread_application_password" "resource-server-1" {
+ application_object_id = azuread_application.resource-server-1.object_id
+}
+
+# Retrieve domain information
+data "azuread_domains" "example" {
+ only_initial = true
+}
+
+# Create a user
+resource "azuread_user" "user" {
+ user_principal_name = "security-${random_string.random.result}@${data.azuread_domains.example.domains.0.domain_name}"
+ display_name = "security"
+ password = "Azure123456@"
+}
+
+resource "azuread_service_principal_delegated_permission_grant" "resource-server-1" {
+ service_principal_object_id = azuread_service_principal.client-1.object_id
+ resource_service_principal_object_id = azuread_service_principal.resource-server-1.object_id
+ claim_values = ["resource-server-1.scope-1"]
+}
+
+resource "null_resource" "set_env" {
+ depends_on = [azuread_service_principal.resource-server-1]
+
+ provisioner "local-exec" {
+ command = "/bin/bash set_identifier_uris.sh"
+ }
+}
diff --git a/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/outputs.tf b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/outputs.tf
new file mode 100644
index 000000000..64a2a45b7
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/outputs.tf
@@ -0,0 +1,37 @@
+output "TENANT_ID" {
+ value = data.azuread_client_config.current.tenant_id
+ description = "The tenant id."
+}
+
+output "CLIENT_1_CLIENT_ID" {
+ value = azuread_application.client-1.application_id
+ description = "The application id of web app."
+}
+
+output "RESOURCE_SERVER_1_CLIENT_ID" {
+ value = azuread_application.resource-server-1.application_id
+ description = "The application id of resource server 1."
+}
+
+output "CLIENT_1_CLIENT_SECRET" {
+ value = azuread_application_password.client-1.value
+ sensitive = true
+ description = "The client secret of web app."
+}
+
+output "RESOURCE_SERVER_1_CLIENT_SECRET" {
+ value = azuread_application_password.resource-server-1.value
+ sensitive = true
+ description = "The client secret of resource server 1."
+}
+
+output "USER_NAME" {
+ value = azuread_user.user.user_principal_name
+ description = "The user name of the user created by terraform."
+}
+
+output "USER_PASSWORD" {
+ value = azuread_user.user.password
+ sensitive = true
+ description = "The password of the user created by terraform."
+}
diff --git a/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/set_identifier_uris.sh b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/set_identifier_uris.sh
new file mode 100644
index 000000000..c066af972
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/set_identifier_uris.sh
@@ -0,0 +1,8 @@
+RESOURCE_SERVER_1_CLIENT_ID=$(terraform output -raw RESOURCE_SERVER_1_CLIENT_ID)
+
+# set identifier_uris
+echo "----------update identifier-uris for RESOURCE_SERVER_1----------"
+az ad app update --id $RESOURCE_SERVER_1_CLIENT_ID --identifier-uris api://$RESOURCE_SERVER_1_CLIENT_ID
+
+
+echo "----------update identifier-uris completed----------"
diff --git a/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/setup_env.sh b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/setup_env.sh
new file mode 100644
index 000000000..40f0e64da
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-check-permissions-by-claims-in-access-token/terraform/setup_env.sh
@@ -0,0 +1,18 @@
+export TENANT_ID=$(terraform -chdir=./terraform output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_ID)
+export RESOURCE_SERVER_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_1_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_SECRET)
+export RESOURCE_SERVER_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_1_CLIENT_SECRET)
+export USER_NAME=$(terraform -chdir=./terraform output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=./terraform output -raw USER_PASSWORD)
+
+echo TENANT_ID=$TENANT_ID
+echo CLIENT_1_CLIENT_ID=$CLIENT_1_CLIENT_ID
+echo RESOURCE_SERVER_1_CLIENT_ID=$RESOURCE_SERVER_1_CLIENT_ID
+echo CLIENT_1_CLIENT_SECRET=$CLIENT_1_CLIENT_SECRET
+echo RESOURCE_SERVER_1_CLIENT_SECRET=$RESOURCE_SERVER_1_CLIENT_SECRET
+
+echo "--------created user--------"
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+
diff --git a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/README.md b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/README.md
new file mode 100644
index 000000000..3a4c28593
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/README.md
@@ -0,0 +1,103 @@
+# Spring Boot application with Azure Active Directory
+
+## What You Need
+
+- [An Azure subscription](https://azure.microsoft.com/free/)
+- [Terraform](https://www.terraform.io/)
+- [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli)
+- [JDK8](https://www.oracle.com/java/technologies/downloads/) or later
+- Maven
+- You can also import the code straight into your IDE:
+ - [IntelliJ IDEA](https://www.jetbrains.com/idea/download)
+
+## Provision Azure Resources Required to Run This Sample
+
+### Authenticate Using the Azure CLI
+Terraform must authenticate to Azure to create infrastructure.
+
+In your terminal, use the Azure CLI tool to setup your account permissions locally.
+
+```shell
+az login --tenant [your-tenant] --allow-no-subscriptions
+```
+
+Your browser window will open and you will be prompted to enter your Azure login credentials. After successful authentication, your terminal will display your subscription information. You do not need to save this output as it is saved in your system for Terraform to use.
+
+```shell
+You have logged in. Now let us find all the subscriptions to which you have access...
+
+[
+ {
+ "cloudName": "AzureCloud",
+ "homeTenantId": "home-Tenant-Id",
+ "id": "subscription-id",
+ "isDefault": true,
+ "managedByTenants": [],
+ "name": "Subscription-Name",
+ "state": "Enabled",
+ "tenantId": "0envbwi39-TenantId",
+ "user": {
+ "name": "your-username@domain.com",
+ "type": "user"
+ }
+ }
+]
+```
+
+### Provision the Resources
+
+After login Azure CLI with your account, now you can use the terraform script to create Azure Resources.
+
+#### Run with Bash
+
+```shell
+# Into the directory of resource-server-support-on-behalf-of-flow
+# Initialize your Terraform configuration
+terraform -chdir=./terraform init
+
+# Apply your Terraform Configuration
+terraform -chdir=./terraform apply -auto-approve
+
+```
+
+It may take a few minutes to run the script. After successful running, you will see prompt information like below:
+
+```shell
+...
+Apply complete! Resources: * added, * changed, * destroyed.
+
+```
+
+You can go to [Azure portal](https://ms.portal.azure.com/) in your web browser to check the resources you created.
+
+### Export Output to Your Local Environment
+Running the command below to export environment values:
+
+#### Run with Bash
+
+```shell
+source ./terraform/setup_env.sh
+```
+
+## Run Locally
+
+In your current terminal, run `source run_all.sh`.
+
+```shell
+source run_all.sh
+```
+
+## Verify This Sample
+
+
+## Clean Up Resources
+After running the sample, if you don't want to run the sample, remember to destroy the Azure resources you created to avoid unnecessary billing.
+
+The terraform destroy command terminates resources managed by your Terraform project.
+To destroy the resources you created.
+
+#### Run with Bash
+
+```shell
+terraform -chdir=./terraform destroy -auto-approve
+```
diff --git a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/client/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/client/src/main/resources/application.yml
index 103320817..4ae27bfdd 100644
--- a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/client/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/client/src/main/resources/application.yml
@@ -1,8 +1,8 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${client-1-client-id}
-# 3. ${client-1-client-secret}
-# 4. ${resource-server-1-client-id}
+# 1. ${TENANT_ID}
+# 2. ${CLIENT_1_CLIENT_ID}
+# 3. ${CLIENT_1_CLIENT_SECRET}
+# 4. ${RESOURCE_SERVER_1_CLIENT_ID}
logging:
level:
@@ -15,12 +15,12 @@ spring:
client:
provider: # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login-common-oauth2-provider
azure-active-directory:
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
user-name-attribute: name
registration:
client-1-resource-server-1:
provider: azure-active-directory
- client-id: ${client-1-client-id}
- client-secret: ${client-1-client-secret}
- scope: openid, profile, offline_access, api://${resource-server-1-client-id}/resource-server-1.scope-1, # Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
+ client-id: ${CLIENT_1_CLIENT_ID}
+ client-secret: ${CLIENT_1_CLIENT_SECRET}
+ scope: openid, profile, offline_access, api://${RESOURCE_SERVER_1_CLIENT_ID}/resource-server-1.scope-1, # Refs: https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
redirect-uri: http://localhost:8080/login/oauth2/code/
diff --git a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/resource-server-1/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/resource-server-1/src/main/resources/application.yml
index 9acaf9a60..70445d6f2 100644
--- a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/resource-server-1/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/resource-server-1/src/main/resources/application.yml
@@ -1,8 +1,8 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${resource-server-1-client-id}
-# 3. ${resource-server-1-client-secret}
-# 4. ${resource-server-2-client-id}
+# 1. ${TENANT_ID}
+# 2. ${RESOURCE_SERVER_1_CLIENT_ID}
+# 3. ${RESOURCE_SERVER_1_CLIENT_SECRET}
+# 4. ${RESOURCE_SERVER_2_CLIENT_ID}
logging:
level:
@@ -15,16 +15,16 @@ spring:
client:
provider:
azure-active-directory:
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0 # Refs: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#webflux-oauth2-login-openid-provider-configuration
registration:
resource-server-1-resource-server-2:
provider: azure-active-directory
- client-id: ${resource-server-1-client-id}
- client-secret: ${resource-server-1-client-secret}
+ client-id: ${RESOURCE_SERVER_1_CLIENT_ID}
+ client-secret: ${RESOURCE_SERVER_1_CLIENT_SECRET}
authorization-grant-type: urn:ietf:params:oauth:grant-type:jwt-bearer
- scope: api://${resource-server-2-client-id}/resource-server-2.scope-1
+ scope: api://${RESOURCE_SERVER_2_CLIENT_ID}/resource-server-2.scope-1
resourceserver:
jwt:
- jwk-set-uri: https://login.microsoftonline.com/${tenant-id}/discovery/v2.0/keys
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0
- audience: ${resource-server-1-client-id}
+ jwk-set-uri: https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0
+ audience: ${RESOURCE_SERVER_1_CLIENT_ID}
diff --git a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/resource-server-2/src/main/resources/application.yml b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/resource-server-2/src/main/resources/application.yml
index 33386397e..0f4c1cb8f 100644
--- a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/resource-server-2/src/main/resources/application.yml
+++ b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/resource-server-2/src/main/resources/application.yml
@@ -1,6 +1,6 @@
# Please fill these placeholders before running this application:
-# 1. ${tenant-id}
-# 2. ${resource-server-2-client-id}
+# 1. ${TENANT_ID}
+# 2. ${RESOURCE_SERVER_2_CLIENT_ID}
logging:
level:
@@ -12,6 +12,6 @@ spring:
oauth2:
resourceserver:
jwt:
- jwk-set-uri: https://login.microsoftonline.com/${tenant-id}/discovery/v2.0/keys
- issuer-uri: https://login.microsoftonline.com/${tenant-id}/v2.0
- audience: ${resource-server-2-client-id}
+ jwk-set-uri: https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys
+ issuer-uri: https://login.microsoftonline.com/${TENANT_ID}/v2.0
+ audience: ${RESOURCE_SERVER_2_CLIENT_ID}
diff --git a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/run_all.sh b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/run_all.sh
new file mode 100644
index 000000000..0c38220d7
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/run_all.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+
+kill -9 $(lsof -t -i tcp:8080)
+kill -9 $(lsof -t -i tcp:8081)
+kill -9 $(lsof -t -i tcp:8082)
+
+mvn clean package spring-boot:repackage -DskipTests -f ../../../pom.xml -pl \
+com.azure.spring:servlet-oauth2-resource-server-support-on-behalf-of-flow-client-application,\
+com.azure.spring:servlet-oauth2-resource-server-support-on-behalf-of-flow-resource-server-1-application,\
+com.azure.spring:servlet-oauth2-resource-server-support-on-behalf-of-flow-resource-server-2-application
+
+export terraform_path="./terraform"
+
+export TENANT_ID=$(terraform -chdir=$terraform_path output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw CLIENT_1_CLIENT_ID)
+export RESOURCE_SERVER_1_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_1_CLIENT_ID)
+export RESOURCE_SERVER_2_CLIENT_ID=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_2_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=$terraform_path output -raw CLIENT_1_CLIENT_SECRET)
+export RESOURCE_SERVER_1_CLIENT_SECRET=$(terraform -chdir=$terraform_path output -raw RESOURCE_SERVER_1_CLIENT_SECRET)
+
+
+echo "Running apps"
+mkdir -p target
+echo "Running client-----------"
+nohup java -jar client/target/*.jar > target/client.log 2>&1 &
+echo "Running resource-server-1-----------"
+nohup java -jar resource-server-1/target/*.jar > target/resource-server-1.log 2>&1 &
+echo "Running resource-server-2-----------"
+nohup java -jar resource-server-2/target/*.jar > target/resource-server-2.log 2>&1 &
+sleep 10
+
+echo "All apps started, please check target folder for logs."
+echo "You can use the user info below to login."
+echo "--------created user--------"
+export USER_NAME=$(terraform -chdir=$terraform_path output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=$terraform_path output -raw USER_PASSWORD)
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+echo "Now you should be able to open browser to access http://localhost:8080 with user above."
diff --git a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/main.tf b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/main.tf
new file mode 100644
index 000000000..6844631fc
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/main.tf
@@ -0,0 +1,247 @@
+terraform {
+ required_providers {
+ azuread = {
+ source = "hashicorp/azuread"
+ version = "2.19.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "3.1.0"
+ }
+ null = {
+ source = "hashicorp/null"
+ version = "3.1.0"
+ }
+ }
+}
+
+resource "random_string" "random" {
+ length = 5
+ min_lower = 5
+ special = false
+}
+
+resource "random_uuid" "resource-server-1-scope-1" {
+}
+
+resource "random_uuid" "resource-server-1-scope-2" {
+}
+
+resource "random_uuid" "resource-server-2-scope-1" {
+}
+
+resource "random_uuid" "resource-server-2-scope-2" {
+}
+
+resource "random_uuid" "resource-server-1-role-1" {
+}
+
+resource "random_uuid" "resource-server-1-role-2" {
+}
+
+data "azuread_client_config" "current" {}
+
+# Configure the Azure Active Directory Provider
+provider "azuread" {
+}
+
+# Configure client-1
+resource "azuread_application" "client-1" {
+ display_name = "client-1-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/",
+ "http://localhost:8080/login/oauth2/code/client-1-resource-server-1",
+ "http://localhost:8080/login/oauth2/code/client-1-resource-server-2"]
+
+ implicit_grant {
+ access_token_issuance_enabled = true
+ id_token_issuance_enabled = true
+ }
+ }
+}
+
+
+# Configure resource-server-2
+resource "azuread_application" "resource-server-2" {
+ display_name = "resource-server-2-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-2.scope-1"
+ admin_consent_display_name = "resource-server-2.scope-1"
+ enabled = true
+ id = random_uuid.resource-server-2-scope-1.result
+ type = "User"
+ value = "resource-server-2.scope-1"
+ }
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-2.scope-2"
+ admin_consent_display_name = "resource-server-2.scope-2"
+ enabled = true
+ id = random_uuid.resource-server-2-scope-2.result
+ type = "User"
+ value = "resource-server-2.scope-2"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+}
+
+
+# Configure resource-server-1
+resource "azuread_application" "resource-server-1" {
+ display_name = "resource-server-1-${random_string.random.result}"
+
+ owners = [data.azuread_client_config.current.object_id]
+ # single tenant
+ sign_in_audience = "AzureADMyOrg"
+
+ api {
+ requested_access_token_version = 2
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-1.scope-1"
+ admin_consent_display_name = "resource-server-1.scope-1"
+ enabled = true
+ id = random_uuid.resource-server-1-scope-1.result
+ type = "User"
+ value = "resource-server-1.scope-1"
+ }
+
+ oauth2_permission_scope {
+ admin_consent_description = "resource-server-1.scope-2"
+ admin_consent_display_name = "resource-server-1.scope-2"
+ enabled = true
+ id = random_uuid.resource-server-1-scope-2.result
+ type = "User"
+ value = "resource-server-1.scope-2"
+ }
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "resource-server-1-role-2"
+ display_name = "resource-server-1-role-2"
+ enabled = true
+ id = random_uuid.resource-server-1-role-2.result
+ value = "resource-server-1-role-2"
+ }
+
+ app_role {
+ allowed_member_types = ["User"]
+ description = "resource-server-1-role-1"
+ display_name = "resource-server-1-role-1"
+ enabled = true
+ id = random_uuid.resource-server-1-role-1.result
+ value = "resource-server-1-role-1"
+ }
+
+ required_resource_access {
+ resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
+
+ resource_access {
+ id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
+ type = "Scope"
+ }
+ }
+
+ required_resource_access {
+ resource_app_id = azuread_application.resource-server-2.application_id # Resource server 2
+
+ # need grant
+ resource_access {
+ id = random_uuid.resource-server-2-scope-1.result # resource-server-2.scope-1
+ type = "Scope"
+ }
+ }
+
+ web {
+ redirect_uris = ["http://localhost:8080/login/oauth2/code/"]
+ }
+}
+
+resource "azuread_service_principal_delegated_permission_grant" "resource-server-1" {
+ service_principal_object_id = azuread_service_principal.resource-server-1.object_id
+ resource_service_principal_object_id = azuread_service_principal.resource-server-2.object_id
+ claim_values = ["resource-server-2.scope-1"]
+}
+
+resource "azuread_service_principal" "client-1" {
+ application_id = azuread_application.client-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_service_principal" "resource-server-1" {
+ application_id = azuread_application.resource-server-1.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+resource "azuread_service_principal" "resource-server-2" {
+ application_id = azuread_application.resource-server-2.application_id
+ app_role_assignment_required = false
+ owners = [data.azuread_client_config.current.object_id]
+}
+
+
+resource "azuread_application_password" "client-1" {
+ application_object_id = azuread_application.client-1.object_id
+}
+
+
+resource "azuread_application_password" "resource-server-1" {
+ application_object_id = azuread_application.resource-server-1.object_id
+}
+
+# Retrieve domain information
+data "azuread_domains" "example" {
+ only_initial = true
+}
+
+# Create a user
+resource "azuread_user" "user" {
+ user_principal_name = "security-${random_string.random.result}@${data.azuread_domains.example.domains.0.domain_name}"
+ display_name = "security"
+ password = "Azure123456@"
+}
+
+resource "null_resource" "set_env" {
+ depends_on = [azuread_service_principal.resource-server-2]
+
+ provisioner "local-exec" {
+ command = "/bin/bash set_identifier_uris.sh"
+ }
+}
diff --git a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/outputs.tf b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/outputs.tf
new file mode 100644
index 000000000..b985e3d70
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/outputs.tf
@@ -0,0 +1,42 @@
+output "TENANT_ID" {
+ value = data.azuread_client_config.current.tenant_id
+ description = "The tenant id."
+}
+
+output "CLIENT_1_CLIENT_ID" {
+ value = azuread_application.client-1.application_id
+ description = "The application id of web app."
+}
+
+output "RESOURCE_SERVER_1_CLIENT_ID" {
+ value = azuread_application.resource-server-1.application_id
+ description = "The application id of resource server 1."
+}
+
+output "RESOURCE_SERVER_2_CLIENT_ID" {
+ value = azuread_application.resource-server-2.application_id
+ description = "The application id of resource server 2."
+}
+
+output "CLIENT_1_CLIENT_SECRET" {
+ value = azuread_application_password.client-1.value
+ sensitive = true
+ description = "The client secret of web app."
+}
+
+output "RESOURCE_SERVER_1_CLIENT_SECRET" {
+ value = azuread_application_password.resource-server-1.value
+ sensitive = true
+ description = "The client secret of resource server 1."
+}
+
+output "USER_NAME" {
+ value = azuread_user.user.user_principal_name
+ description = "The user name of the user created by terraform."
+}
+
+output "USER_PASSWORD" {
+ value = azuread_user.user.password
+ sensitive = true
+ description = "The password of the user created by terraform."
+}
diff --git a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/set_identifier_uris.sh b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/set_identifier_uris.sh
new file mode 100644
index 000000000..9510b7167
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/set_identifier_uris.sh
@@ -0,0 +1,11 @@
+RESOURCE_SERVER_1_CLIENT_ID=$(terraform output -raw RESOURCE_SERVER_1_CLIENT_ID)
+RESOURCE_SERVER_2_CLIENT_ID=$(terraform output -raw RESOURCE_SERVER_2_CLIENT_ID)
+
+# set identifier_uris
+echo "----------update identifier-uris for RESOURCE_SERVER_1----------"
+az ad app update --id $RESOURCE_SERVER_1_CLIENT_ID --identifier-uris api://$RESOURCE_SERVER_1_CLIENT_ID
+
+echo "----------update identifier-uris for RESOURCE_SERVER_2----------"
+az ad app update --id $RESOURCE_SERVER_2_CLIENT_ID --identifier-uris api://$RESOURCE_SERVER_2_CLIENT_ID
+
+echo "----------update identifier-uris completed----------"
diff --git a/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/setup_env.sh b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/setup_env.sh
new file mode 100644
index 000000000..c91569d95
--- /dev/null
+++ b/aad/spring-security/servlet/oauth2/resource-server-support-on-behalf-of-flow/terraform/setup_env.sh
@@ -0,0 +1,20 @@
+export TENANT_ID=$(terraform -chdir=./terraform output -raw TENANT_ID)
+export CLIENT_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_ID)
+export RESOURCE_SERVER_1_CLIENT_ID=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_1_CLIENT_ID)
+export RESOURCE_SERVER_2_CLIENT_ID=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_2_CLIENT_ID)
+export CLIENT_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw CLIENT_1_CLIENT_SECRET)
+export RESOURCE_SERVER_1_CLIENT_SECRET=$(terraform -chdir=./terraform output -raw RESOURCE_SERVER_1_CLIENT_SECRET)
+export USER_NAME=$(terraform -chdir=./terraform output -raw USER_NAME)
+export USER_PASSWORD=$(terraform -chdir=./terraform output -raw USER_PASSWORD)
+
+echo TENANT_ID=$TENANT_ID
+echo CLIENT_1_CLIENT_ID=$CLIENT_1_CLIENT_ID
+echo RESOURCE_SERVER_1_CLIENT_ID=$RESOURCE_SERVER_1_CLIENT_ID
+echo RESOURCE_SERVER_2_CLIENT_ID=$RESOURCE_SERVER_2_CLIENT_ID
+echo CLIENT_1_CLIENT_SECRET=$CLIENT_1_CLIENT_SECRET
+echo RESOURCE_SERVER_1_CLIENT_SECRET=$RESOURCE_SERVER_1_CLIENT_SECRET
+
+echo "--------created user--------"
+echo USER_NAME=$USER_NAME
+echo USER_PASSWORD=$USER_PASSWORD
+
diff --git a/pom.xml b/pom.xml
index c15acb88c..6eb86e321 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,11 +30,9 @@
- aad/spring-cloud-azure-starter-active-directory/aad-resource-server
+ aad/spring-cloud-azure-starter-active-directory/web-client-access-resource-server
aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter
aad/spring-cloud-azure-starter-active-directory/aad-resource-server-by-filter-stateless
- aad/spring-cloud-azure-starter-active-directory/aad-resource-server-obo
- aad/spring-cloud-azure-starter-active-directory/aad-web-application
aad/spring-cloud-azure-starter-active-directory/aad-web-application-and-resource-server
aad/spring-cloud-azure-starter-active-directory-b2c/aad-b2c-web-application
aad/spring-cloud-azure-starter-active-directory-b2c/aad-b2c-resource-server