Azure 應用程式閘道 是可在應用層級運作的 Web 流量負載平衡器。 它可以作為 Web 用戶端的單一連絡點,並可設定為根據 HTTP 屬性將 Web 流量路由傳送至各種後端,例如 URI 路徑等。 應用程式閘道 具有 WebSocket 的原生支援 - 使用者不需要設定任何特殊項目來啟用 WebSocket。
在本指南中,我們會示範如何使用 Azure 應用程式閘道 來保護Web PubSub資源。 我們只允許來自 應用程式閘道的流量,並停用您 Web PubSub 資源的公用流量,以達到更高的安全性層級。
如下圖所示,您必須為 Web PubSub 資源設定私人端點。 此私人端點必須與您的 應用程式閘道 位於相同的 虛擬網絡 中。
本指南採用逐步方法。 首先,我們會設定 應用程式閘道,讓 Web PubSub 資源的流量能夠順利通過。 其次,我們會套用 Web PubSub 的存取控制功能,只允許來自 應用程式閘道 的流量。
步驟 1:將 應用程式閘道 設定為將流量 Proxy 至 Web PubSub 資源
此圖說明我們將在步驟 1 中達成的目標。
建立 Azure 應用程式閘道執行個體
在 Azure 入口網站 上,搜尋 Azure 應用程式閘道 並遵循步驟來建立資源。 圖表中會醒目提示重要步驟。
Azure 資源需要 虛擬網絡,才能安全地彼此通訊。 Azure 應用程式閘道 需要專用的子網,這是我們建立的子網。 基於本指南的目的,在步驟 1 中,您的 Azure 應用程式閘道 資源會透過公用因特網將流量轉送至您的 Web PubSub 資源。 在步驟 2 中,我們會建立另一個子網來存放 Web PubSub 資源,讓您的 Azure 應用程式閘道 透過 虛擬網絡 安全地將流量轉送至您的 Web PubSub 資源。
設定 Azure 應用程式閘道
設定 Azure 應用程式閘道 需要三個元件。
- 前端
- 後端
- 路由規則
前端是您 Azure 應用程式閘道的IP位址。 由於我們使用 Azure 應用程式閘道 作為 Web 用戶端的單一連絡點,因此我們需要為其建立公用 IP。
後端是您 應用程式閘道 資源可以傳送流量的資源。 在我們的案例中,我們有一個目標,即 Web PubSub 資源。
尋找您想要用來遵循本指南 Azure 入口網站 的現有 Web PubSub 資源的主機名。 看起來應該像這樣, xxxx.webpubsub.azure.com。
設定前端和後端之後,我們需要設定連線前端和後端的路由規則。 路由規則會告知 應用程式閘道 如何將流量路由傳送至何處。
首先,我們會設定接聽程式。 此設定會告知 應用程式閘道 在埠 80 上接聽 HTTP 流量。
其次,我們會設定後端目標。 我們會將後端目標設定為我們稍早建立的後端集區,也就是 Web PubSub 資源。 此外,我們需要指定 應用程式閘道 應如何轉送流量。 您可以透過 後端設定來完成它。
Web PubSub 服務只接受 HTTP 流量。 因此,我們會指示 應用程式閘道 使用 HTTP 與 Web PubSub 通訊。 為了讓本指南保持專注,我們讓 應用程式閘道 挑選主機。 建議的做法是在生產環境中設定自定義網域。
設定三個元件時,您應該會看到類似螢幕快照的內容。 您可以透過 應用程式閘道 將流量的流程可視化,例如:
- Web 用戶端會將要求傳送至 應用程式閘道 資源的公用IP。
- 應用程式閘道 藉由諮詢用戶設定的路由規則來路由流量。
- 當路由規則相符時,流量會導向至指定的後端目標。
值得強調的一件事是,您以完全相同的方式設定 非 WebSocket 連線。 您可以深入瞭解 應用程式閘道 原生支援 Proxy 處理 WebSocket 連線
最後要更新的是後端 健康情況探查。 選取 [設定 -> 健康情況探查],然後選取產生的健康情況探查 設定、更新 路徑 , /api/health 並將其他人維持不變。
測試並確認已正確設定 應用程式閘道
確認您的 Web PubSub 資源狀況良好
將要求傳送至 Web PubSub 資源的無效端點,並預期來自 Web PubSub 的錯誤訊息。
curl https://<your-web-pubsub-resource-endpoint>/client
您應該會看到錯誤訊息「『中樞』的值無效」。此錯誤顯示 Web PubSub 服務已成功收到您的要求並據以回應。
確認 應用程式閘道 Proxy 流量到您的 Web PubSub 資源
重複類似的步驟,並預期相同的錯誤訊息。
curl http://<public-ip-of-your-application-gateway-resource>/client
您應該會看到相同的錯誤訊息「『中樞值無效」。此錯誤顯示您的 應用程式閘道 資源已使用已設定的路由規則成功路由傳送流量。
測試並確認 應用程式閘道 可以 Proxy WebSocket 連線
透過 Web PubSub 發佈訊息
我們會建立簡單的程式,以定期模擬透過 Web PubSub 發佈訊息的伺服器。 我們會在步驟 1 本機執行程式,以確認一切正常運作,並在步驟 2 中,我們會將相同的應用程式部署至 Azure App 服務。
建立資料夾結構
mkdir server && cd server
touch package.json && touch publish.js
複製原始碼
將程式代碼複製到您建立的 package.json 檔案。
{
"scripts": {
"start": "node ./publish.js"
},
"dependencies": {
"@azure/web-pubsub": "^1.1.1",
"express": "^4.19.2"
}
}
將程式代碼複製到您建立的 publish.js 檔案。
const express = require("express")
// Uses the service SDK, which makes it easy to consume the capabilities of the service
const { WebPubSubServiceClient } = require('@azure/web-pubsub');
const app = express()
const PORT = 3000
// Hardcodes the hub name
const hub = "myHub1";
// Grabs the connection string stored as an environment variable
let webpubsub = new WebPubSubServiceClient(process.env.WebPubSubConnectionString, hub);
// Serves the files found in the "public" directory
app.use(express.static("public"))
// Returns Web PubSub's access token
app.get("/negotiate", async (req, res) => {
let token = await webpubsub.getClientAccessToken()
let url = token.url
res.json({
url
})
}
// Every 2 seconds, we ask Web PubSub service to send all connected clients the message "hello, world"
setInterval(() => {
webpubsub.sendToAll("hello, world", { contentType: "text/plain" });
}, 2000);
// Starts the server
app.listen(process.env.PORT || PORT, () => console.log(`server running on ${PORT}`));
安裝相依性並執行程式
在 Azure 入口網站 上,尋找connection string您 Web PubSub 資源的 。
npm install
## Set environment variable
export WebPubSubConnectionString="<replace with the connection string of your Web PubSub resource>"
npm run start
您應該會在控制台中看到「在 3000 上執行的伺服器」。 程式每隔 2 秒會要求 Web PubSub 服務將訊息廣播給所有連線的 Web 用戶端。 雖然目前沒有任何 Web 用戶端與您的 Web PubSub 資源連線,但您可以啟用 即時追蹤工具功能來查看此流程,您可以在其中即時監視重要的記錄。
在瀏覽器中接收訊息
如果我們未收到廣播的訊息,它就不會照亮。 在您稍早建立的伺服器資料夾內,讓我們建立簡單的 HTML 檔案,我們將客戶端程式代碼放在其中。 應用程式 express 會提供此靜態檔案。
mkdir public && cd public
touch index.html
複製用戶端程序代碼
將程式代碼複製到 index.html
<!DOCTYPE html>
<body>
<script type="module">
const endpoint = "http://localhost:3000"
// Gets an access token through which the client connects with your Web PubSub resource
const webPubSubUrl = await getWebPubSubAccessToken(endpoint)
// Opens a WebSocket connection with your Web PubSub resource using browser native WebSocket API
const socket = new WebSocket(webPubSubUrl)
socket.addEventListener("open", () => {
console.log("connection opened")
})
// Prints out the message when it arrives
socket.addEventListener("message", (msg) => {
console.log(msg)
})
async function getWebPubSubAccessToken(endpoint) {
const response = await fetch(endpoint + "/negotiate")
const { url } = await response.json()
return url
}
</script>
</body>
</html>
執行用戶端程式
開啟您慣用的網頁瀏覽器並流覽 http://localhost:3000,其中我們的伺服器正在接聽。
請確定您仍然執行 publish.js 中。 如果您檢查頁面,請開啟 [網络] 和 [控制台] 面板,您應該會看到用戶端已成功與 Web PubSub 資源連線,並取得廣播的訊息。
透過 應用程式閘道 Proxy WebSocket 連線
由於 應用程式閘道 具有 WebSocket 的原生支援,因此我們不需要變更 應用程式閘道 資源上的任何設定。 我們只需要將用戶端指向的端點變更為 。
找出 publish.js 檔案並進行兩項變更。
- 宣告變數來保存 應用程式閘道 資源的公用IP。
- 變更初始化變數
url的行。let url=token.url。
// ... code omitted from before
const appGatewayEndpoint = process.env.appGatewayEndpoint
app.get("/negotiate", async (req, res) => {
const token = await webpubsub.getClientAccessToken()
const url = "ws://" + appGatewayEndpoint + token.url.split(".com")[1]
// ... code omitted from before
})
// ... code omitted from before
尋找 應用程式閘道 資源的公用IP,並設定環境變數。
export appGatewayEndpoint="<replace with the public IP of your Application Gateway resource>"
要注意的三點。
- 我們會使用
ws://而非wss://,因為您的 應用程式閘道 已設定為只接聽http流量。 - 在生產環境中,最好為 應用程式閘道 資源設定自定義網域,並將其設定為只接受 HTTP。
- 我們需要保留存取令牌,因為它會編碼客戶端的認證,以與 Web PubSub 資源連線。
開啟瀏覽器並再次流覽http://localhost:3000,您可以確認 WebSocket 已成功透過 應用程式閘道 代理,並大約每 2 秒接收來自 應用程式閘道 的訊息。
步驟 1 的回顧
我們已到達步驟 1 的結尾。 如果您已遵循步驟 1,您應該會看到 Web PubSub 資源可直接由您的 Web 用戶端存取,並透過 應用程式閘道 間接存取。 您也看到 應用程式閘道 對 WebSocket 的原生支援作用。 啟用它不需要進行任何設定變更。 我們只需要確定 Web 用戶端指向 應用程式閘道 端點。 從 Web PubSub 服務 SDK 產生的其餘存取 URL 應該保持不變。
在步驟 2 中,我們會關閉 Web PubSub 資源的公用存取權,使其更安全。
步驟 2:停用 Web PubSub 資源的公用存取
步驟 1 的結果是,您的 Web PubSub 資源可透過公用因特網和 應用程式閘道 存取。 因為您的 Web PubSub 資源不在同一個 虛擬網絡 中,所以當 應用程式閘道 將流量轉送至 Web PubSub 資源時,它會透過公用因特網到達 Web PubSub 的公用端點。 這種情況不理想。
Web PubSub 服務支援設定訪問控制。 其中一種設定是停用從公用因特網存取。 當您完成時,請務必按 「儲存」。
現在,如果您執行相同的命令,而不是像之前一樣看到「無效的中樞名稱」,您會看到 403 Forbidden。
curl https://<your-web-pubsub-resource-endpoint>/client
現在 Web PubSub 資源已停用公用存取。 其中一個影響是,應用程式閘道 在步驟 1 中設定時無法連線到它。 如果您針對 應用程式閘道 端點執行相同的命令,您會看到 504 Gateway Time-out。
curl http://<public-ip-of-your-application-gateway-resource>/client
我們需要將您的 Web PubSub 資源放在您 應用程式閘道 所在的相同 虛擬網絡 中。 我們會藉由建立私人端點來達成此目的。 您可以在這裡深入瞭解私人端點。
為您的私人端點建立個別的子網
在步驟 1 中,我們建立了 應用程式閘道 的子網。 應用程式閘道 需要自己的子網,因此我們需要為您的私人端點建立另一個子網。
找出我們稍早建立 虛擬網絡 資源,並建立新的子網。
為您的 Web PubSub 資源建立私人端點
在 Azure 入口網站 上找出您的 Web PubSub 資源,然後移至 [網路] 刀鋒視窗。
在與 Web PubSub 資源相同的區域中建立私人端點。
選取我們剛才建立的個別子網。
啟用私人 DNS 整合
重新整理 應用程式閘道 資源的後端集區
您的 應用程式閘道 資源不知道您為 Web PubSub 資源建立了私人端點。 找出您的 應用程式閘道 資源並重新整理後端集區。
現在,如果您再次執行此命令,您應該會再次看到「無效的中樞名稱」,這是預期的。 它會顯示透過 虛擬網絡 而非公用因特網 應用程式閘道 Proxy。
curl http://<public-ip-of-your-application-gateway-resource>/client
將發佈程式部署為 App Service Web 應用程式
由於 Web PubSub 資源的公用存取已停用,我們的本機 publish.js 程式無法連線到資源。 我們需要將程式部署為 Web 應用程式到 Web PubSub 資源所在的相同 虛擬網絡。
將 Web 應用程式部署為 ZIP 檔案
在我們可以壓縮原始程式碼並將其部署到 Azure App 服務 之前,我們需要對用戶端程式代碼進行小變更。
/negotiate端點將不再從 localhost提供。
在公用資料夾中找出 index.html ,然後變更宣告變數的 endpoint 行。 您需要將它取代為 Web 應用程式的功能變數名稱。
<script>
// ...code omitted from before
const endpoint = "<replace with your default domain name of your web app>"
// ...code omitted from before
</script>
Web 應用程式提供方便的命令,以將應用程式部署為 ZIP 檔案。
您可以深入瞭解 az webapp up 命令 及其自動執行的工作。
找出您在步驟 1 中建立的伺服器資料夾。
## Makes sure you are in the right working directory
cd server
## Make sure you have Azure CLI installed and log into your Azure account.
az login
## Creates a ZIP file with the content in the server folder and deploys it as a Web App
az webapp up \
--sku B1 \
--name <the-name-of-your-web-app> \
--location <the-same-location-as-your-Web-PubSub-resource>
注意
如果您已遵循本指南,您可能需要切換至到目前為止所建立資源的 Azure 訂用帳戶。 若要切換訂用帳戶,請遵循本檔文章中所述的命令。
設定環境變數
publish.js程序啟動時,App Service 會讓環境變數可供程式取用。
我們需要設定兩個環境變數,並提供給 publish.js。
- 在 Azure 入口網站 上尋找您 連接字串 至 Web PubSub 服務,並設定
WebPubSubConnectionString環境變數。 - 尋找 應用程式閘道 資源的前端公用IP,並設定
appGatewayEndpoint環境變數。
在 Web 應用程式上啟用 虛擬網絡 整合
App Service 需要您 虛擬網絡 中的專用子網。 移至您的 虛擬網絡 資源,並建立新的子網,就像您為 Web PubSub 資源所做的一樣。
建立新的子網之後,請移至 Web 應用程式資源的 [網络] 刀鋒視窗,然後啟用 虛擬網絡 整合。
請確定您在 Web PubSub 資源所在的 虛擬網絡 選取相同。
關閉自動 HTTP 重新導向
根據預設,Web 應用程式會將 HTTP 流量重新導向至 HTTP。 我們需要停用此預設行為。 不建議用於生產工作負載。
確認所有專案都正常運作
到目前為止,在步驟 2 中,您
- 已停用 Web PubSub 資源的公用存取權,
- 為其建立私人端點,
- 重新整理 應用程式閘道 資源的後端集區,使其可以連線到您的 Web PubSub 資源
- 更新用戶端取得存取令牌的端點,以便與 Web PubSub 資源連線
- 部署
publish.js為 Web 應用程式至相同的 虛擬網絡, - 在您的 Web 應用程式資源上設定兩個環境變數:
- 已停用 Web 應用程式將 HTTP 流量重新導向至 HTTP 的預設行為。
現在,開啟網頁瀏覽器,然後輸入 Web 應用程式的功能變數名稱。 如果您檢查頁面,請開啟 [網络] 面板,您會看到用戶端前往 Web App 以取得存取令牌,然後使用令牌來建立與 應用程式閘道 的 WebSocket 連線。
如果您已開啟主控台面板,也會看到廣播的訊息。