教學:從 Java JBoss EAP 在 Azure App 服務 連接 MySQL 資料庫

在這個教學中,你將學習如何利用管理身份將Java JBoss EAP 應用程式Azure App 服務連接到 適用於 MySQL 的 Azure 資料庫 資料庫。 App Service 可以使用 managed identity來提供對 適用於 MySQL 的 Azure 資料庫 及其他 Azure 服務的安全存取。 管理身份消除了在應用程式中使用秘密(例如環境變數中的憑證)的需求。

本教學使用 Azure CLI 指令來完成以下任務:

  • 建立適用於 MySQL 的 Azure 資料庫伺服器和資料庫。
  • 透過 WAR 套件部署範例 JBoss EAP 應用程式至 App Service。
  • 將 Spring Boot 網頁應用程式設定為使用 Microsoft Entra 認證與 MySQL 資料庫。
  • 利用服務連接器與管理身份驗證將網頁應用程式連接到 MySQL 資料庫。

必要條件

  • 一個具備以下條件的 Azure 訂閱: - 擁有 Microsoft Entra 角色分配權限 - 擁有 Azure 資源寫入權限 - 所在的 Azure 區域支援 Service Connector - 擁有足夠的 App Service 支援及配額 來進行教學。

  • Microsoft.ServiceLinker 和 Microsoft.DBforMySQL 資源提供者已註冊在您的Azure訂閱中。 你可以執行 az provider register -n Microsoft.[service] 來註冊服務提供者。

  • git 以存取並複製樣本庫。

  • 可使用 Azure Cloud Shell 來執行教學步驟;或若您偏好在本地執行,則需要先完成以下先決條件與步驟:

    • Java JDK 已安裝

    • Maven 安裝

    • jq 已安裝

    • MySQL 用戶端 已安裝

    • 安裝Azure CLI 2.46.0 或更高版本。 若要檢查您的版本,請執行 az --version。 要升級,請執行 az upgrade。

      如果你是在本地經營:

      1. 請使用 az login 並依照提示登入Azure。
      2. 如果你的登入憑證連結了多個Azure訂閱,請執行 az account set --subscription <subscription-ID> 選擇正確的訂閱。

設定您的環境

  1. 安裝下列 Azure CLI 擴充功能:

    az extension add --name serviceconnector-passwordless --upgrade
    az extension add --name rdbms-connect
    
  2. 執行以下指令來複製範例儲存庫,並切換目錄到範例應用程式專案資料夾。 從這個資料夾執行所有剩餘指令。

    git clone https://github.com/Azure-Samples/Passwordless-Connections-for-Java-Apps
    cd Passwordless-Connections-for-Java-Apps/JakartaEE/jboss-eap/
    
  3. 為本教學定義以下環境變數,將 <region> 佔位符替換為有效值。 LOCATION 必須是Azure區域,且你的訂閱有足夠的配額來創造Azure資源,且對任何服務都沒有限制。

    LOCATION="<region>"
    RESOURCE_GROUP="mysql-mi-webapp"
    
  4. 建立一個Azure資源群組來包含所有專案資源。 系統會快取資源群組名稱,並自動套用至後續命令。

    az group create --name $RESOURCE_GROUP --location $LOCATION
    

建立適用於 MySQL 的 Azure 資料庫

在你的訂閱中建立 適用於 MySQL 的 Azure 資料庫 的伺服器及資料庫。 Spring Boot 應用程式會連接到這個資料庫,並在執行時儲存資料,無論你在哪裡執行應用程式,應用程式狀態都會持續存在。

  1. 執行以下指令來建立一個 適用於 MySQL 的 Azure 資料庫 伺服器。 MYSQL_HOST 名稱必須在整個 Azure 中唯一。

    注意

    雖然指令定義了管理員帳號,但該帳號並未被使用,因為所有管理任務都是由 Microsoft Entra 管理帳號執行。

    export MYSQL_ADMIN_USER=azureuser
    export MYSQL_ADMIN_PASSWORD="AdminPassword1"
    export RAND_ID=$RANDOM
    export MYSQL_HOST="mysql-mi-$RAND_ID"
    az mysql flexible-server create \
        --name $MYSQL_HOST \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION \
        --admin-user $MYSQL_ADMIN_USER \
        --admin-password $MYSQL_ADMIN_PASSWORD \
        --public-access 0.0.0.0 \
        --tier Burstable \
        --sku-name Standard_B1ms \
        --storage-size 32
    
  2. 建立一個為應用程式命名 checklist 的資料庫。

    export DATABASE_NAME="checklist"
    az mysql flexible-server db create \
        --resource-group $RESOURCE_GROUP \
        --server-name $MYSQL_HOST \
        --database-name $DATABASE_NAME
    
  3. 開啟防火牆,允許從你目前的 IP 位址連接到資料庫。

    # Create a temporary firewall rule to allow connections from your current machine to the MySQL server
    export MY_IP=$(curl http://whatismyip.akamai.com)
    az mysql flexible-server firewall-rule create \
        --resource-group $RESOURCE_GROUP \
        --name $MYSQL_HOST \
        --rule-name AllowCurrentMachineToConnect \
        --start-ip-address ${MY_IP} \
        --end-ip-address ${MY_IP}
    
  4. 連接資料庫,並依照 /azure/init-db.sql 範例專案檔中指定的資料表建立。

    export DATABASE_FQDN=${MYSQL_HOST}.mysql.database.azure.com
    export CURRENT_USER=$(az account show --query user.name --output tsv)
    export RDBMS_ACCESS_TOKEN=$(az account get-access-token \
        --resource-type oss-rdbms \
        --output tsv \
        --query accessToken)
    mysql -h "${DATABASE_FQDN}" --user "${CURRENT_USER}" --password="$RDBMS_ACCESS_TOKEN" < azure/init-db.sql
    
  5. 移除暫時性的防火牆規則。

    az mysql flexible-server firewall-rule delete \
        --resource-group $RESOURCE_GROUP \
        --name $MYSQL_HOST \
        --rule-name AllowCurrentMachineToConnect
    

建立 App Service 資源

在 Linux 上建立一個 App Service JBoss EAP 資源。 JBoss EAP 需要 Premium sku 等級。

# Create an App Service plan
export APPSERVICE_PLAN="mysql-mi-plan"
export APPSERVICE_NAME="mysql-mi-app"
az appservice plan create \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_PLAN \
    --location $LOCATION \
    --sku P1V3 \
    --is-linux

# Create an App Service web app
az webapp create \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_NAME \
    --plan $APPSERVICE_PLAN \
    --runtime "JBOSSEAP:7-java8"

建立及設定使用者指派的受控識別

請使用以下指令建立一個 Azure 用戶指派的管理身份,用於 Microsoft Entra 認證。 如需詳細資訊,請參閱為適用於 MySQL 的 Azure 資料庫 - 彈性伺服器設定 Microsoft Entra 驗證。

export USER_IDENTITY_NAME="my-user-assigned-identity"
export IDENTITY_RESOURCE_ID=$(az identity create \
    --name $USER_IDENTITY_NAME \
    --resource-group $RESOURCE_GROUP \
    --query id \
    --output tsv)

授予新使用者指派的身份 User.Read.All、 、 GroupMember.Read.All及 Application.Read.All 權限。 或者,授與身分識別目錄讀取者 Microsoft Entra 內建角色。

Azure CLI 不支援來分配 Microsoft Entra 權限或角色。 你可以使用 Microsoft Entra 系統管理中心、Microsoft Graph PowerShell 或 Microsoft Graph API 來建立指派。 如需詳細資訊,請參閱 指派Microsoft Entra 角色。

注意

要新增這些指派,您必須在Microsoft Entra租戶中至少擁有 Privileged Role Administrator 角色或權限。 如果你沒有這個角色,請請你的 全域管理員 或 特權角色管理員 授權權限。

使用受管理身份來連結服務

使用 Service Connector 將你的 App Service JBoss EAP 網頁應用程式連接到 MySQL 資料庫,並使用管理身份。 Service Connector 在背景執行以下任務:

  • 將目前登入的使用者設定為 Microsoft Entra 資料庫管理員。
  • 針對應用程式啟用系統指派的受控身分識別。
  • 為系統指派的管理身份新增資料庫使用者,並授予該使用者所有資料庫權限。
  • 在應用程式的 AZURE_MYSQL_CONNECTIONSTRING 中新增了一個名為 的連接字串。

請使用以下 az webapp connection create 指令,將你的應用程式連接到 MySQL 資料庫,使用管理身份。

az webapp connection create mysql-flexible \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_NAME \
    --target-resource-group $RESOURCE_GROUP \
    --server $MYSQL_HOST \
    --database $DATABASE_NAME \
    --system-identity mysql-identity-id=$IDENTITY_RESOURCE_ID \
    --client-type java

建置和部署應用程式

  1. 執行以下程式碼,將無密碼認證外掛加入 Service Connector 產生的 連接字串 中。 應用程式啟動腳本會引用這個連線字串。

    export PASSWORDLESS_URL=$(\
        az webapp config appsettings list \
            --resource-group $RESOURCE_GROUP \
            --name $APPSERVICE_NAME \
        | jq -c '.[] \
        | select ( .name == "AZURE_MYSQL_CONNECTIONSTRING" ) \
        | .value' \
        | sed 's/"//g')
    # Create a new environment variable with the connection string including the passwordless authentication plugin
    export PASSWORDLESS_URL=${PASSWORDLESS_URL}'&defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin'
    az webapp config appsettings set \
        --resource-group $RESOURCE_GROUP \
        --name $APPSERVICE_NAME \
        --settings "AZURE_MYSQL_CONNECTIONSTRING_PASSWORDLESS=${PASSWORDLESS_URL}"
    
  2. 用範例應用程式中的 pom.xml 檔案來產生 WAR 檔案來建立應用程式。

    mvn clean package -DskipTests
    
  3. 將 WAR 檔案和啟動腳本部署到 App Service。

    az webapp deploy \
        --resource-group $RESOURCE_GROUP \
        --name $APPSERVICE_NAME \
        --src-path target/ROOT.war \
        --type war
    az webapp deploy \
        --resource-group $RESOURCE_GROUP \
        --name $APPSERVICE_NAME \
        --src-path src/main/webapp/WEB-INF/createMySQLDataSource.sh \
        --type startup
    

測試應用程式

  1. 執行以下程式碼,建立包含一些清單項目的清單。

    export WEBAPP_URL=$(az webapp show \
        --resource-group $RESOURCE_GROUP \
        --name $APPSERVICE_NAME \
        --query defaultHostName \
        --output tsv)/$DATABASE_NAME
    
    # Create a list
    curl -X POST -H "Content-Type: application/json" -d '{"name": "list1","date": "2022-03-21T00:00:00","description": "Sample checklist"}' https://${WEBAPP_URL}
    
    # Create few items on the list 1
    curl -X POST -H "Content-Type: application/json" -d '{"description": "item 1"}' https://${WEBAPP_URL}/1/item
    curl -X POST -H "Content-Type: application/json" -d '{"description": "item 2"}' https://${WEBAPP_URL}/1/item
    curl -X POST -H "Content-Type: application/json" -d '{"description": "item 3"}' https://${WEBAPP_URL}/1/item
    
  2. 如果你是在本地工作,請執行以下程式碼來查看應用程式:

    # Get all list items
    curl https://${WEBAPP_URL}
    
    # Get list item 1
    curl https://${WEBAPP_URL}/1
    

    Cloud Shell無法開啟本地瀏覽器,如果你正在Cloud Shell工作,最簡單的瀏覽方式是選擇應用程式Azure入口頁面頂端的Browse或Default domain連結。 然後在瀏覽器中將 /checklist 網址加上或 /checklist/1 加到末尾,例如 https://mysql-mi-app.azurewebsites.net/checklist。

清除資源

完成這個教學後,你可以刪除你創建的資源來避免進一步收費。 刪除資源群組以刪除其中包含的所有資源。 執行指令前,務必確定你不再需要這些資源。

az group delete --name $RESOURCE_GROUP --no-wait

刪除所有資源可能需要一些時間。 該 --no-wait 參數允許指令立即返回。