共用方式為


使用 OpenID Connect 和 Azure Active Directory 授權 Web 應用程式的存取權

警告

此內容適用於較舊的 Azure AD v1.0 端點。 針對新專案使用 Microsoft身分識別平臺

OpenID Connect 是建置在 OAuth 2.0 通訊協定之上的簡單身分識別層。 OAuth 2.0 會定義用來取得和使用 存取令牌 來存取受保護資源的機制,但不會定義提供身分識別資訊的標準方法。 OpenID Connect 會將驗證實作為 OAuth 2.0 授權程式的延伸模組。 它會以 id_token 的形式驗證使用者身分識別,提供使用者的基本個人資料資訊。

如果您要建置裝載在伺服器上並透過瀏覽器存取的 Web 應用程式,則 OpenID Connect 是我們的建議。

向AD租用戶註冊您的應用程式

首先,向 Azure Active Directory (Azure AD) 租用戶註冊您的應用程式。 這會提供您應用程式的應用程式識別碼,並讓它接收令牌。

  1. 登入 Azure 入口網站

  2. 選取頁面右上角的帳戶,然後選取 [切換目錄 ] 瀏覽,然後選取適當的租使用者,以選擇您的 Azure AD 租使用者。

    • 如果您帳戶下只有一個 Azure AD 租使用者,或已選取適當的 Azure AD 租使用者,請略過此步驟。
  3. 在 Azure 入口網站中,搜尋並選取 [Azure Active Directory]。

  4. Azure Active Directory 左側選單中,選取 [ 應用程式註冊],然後選取 [ 新增註冊]。

  5. 遵循提示並建立新的應用程式。 本教程中,無論是 Web 應用程式或公眾客戶端應用程式(行動和桌面),都沒有區別。但如果您想要關於 Web 應用程式或公眾客戶端應用程式的特定範例,請參閱我們的 快速入門

    • 名稱 是應用程式名稱,並將您的應用程式描述給使用者。
    • 在 [支援的帳戶類型] 底下,選取 [任何組織目錄中的帳戶及個人的 Microsoft 帳戶]
    • 提供 重新導向 URI。 對於 Web 應用程式,這是使用者可以登入的應用程式基底 URL。 例如: http://localhost:12345 。 針對公用用戶端(行動裝置和桌面版),Azure AD 會使用它來傳回令牌回應。 輸入應用程式特定的值。 例如: http://MyFirstAADApp
  6. 完成註冊之後,Azure AD 會將應用程式指派唯一的用戶端標識碼( 應用程式識別符)。 在下一節中,您需要此值,因此請從應用程式頁面複製此值。

  7. 若要在 Azure 入口網站中尋找您的應用程式,請選取 [ 應用程式註冊],然後選取 [ 檢視所有應用程式]。

使用 OpenID Connect 的驗證流程

最基本的登入流程包含下列步驟 , 其中每一個都詳述如下。

OpenId Connect 驗證流程

OpenID Connect 元數據檔

OpenID Connect 描述元數據檔,其中包含應用程式執行登入所需的大部分資訊。 這包括要使用的 URL,以及服務公開簽署金鑰的位置等資訊。 OpenID Connect 元數據檔位於:

https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration

元數據是簡單的 JavaScript 物件表示法 (JSON) 檔。 如需範例,請參閱下列代碼段。 代碼段的內容會在 OpenID Connect 規格中完整描述。 請注意,提供租使用者標識碼而不是 common 取代上述 {tenant} 會導致傳回 JSON 物件中的租使用者特定 URI。

{
    "authorization_endpoint": "https://login.microsoftonline.com/{tenant}/oauth2/authorize",
    "token_endpoint": "https://login.microsoftonline.com/{tenant}/oauth2/token",
    "token_endpoint_auth_methods_supported":
    [
        "client_secret_post",
        "private_key_jwt",
        "client_secret_basic"
    ],
    "jwks_uri": "https://login.microsoftonline.com/common/discovery/keys"
    "userinfo_endpoint":"https://login.microsoftonline.com/{tenant}/openid/userinfo",
    ...
}

如果您的應用程式因使用 宣告對應 功能而具有自訂簽署金鑰,您必須附加包含 appid 應用程式識別碼的查詢參數,才能取得 jwks_uri 指向您應用程式的簽署金鑰資訊。 例如:https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration?appid=6731de76-14a6-49ae-97bc-6eba6914391e 包含 jwks_urihttps://login.microsoftonline.com/{tenant}/discovery/keys?appid=6731de76-14a6-49ae-97bc-6eba6914391e

傳送登入要求

當您的 Web 應用程式需要驗證使用者時,它必須將使用者 /authorize 導向端點。 此要求與 OAuth 2.0 授權碼流程的第一回合類似,但有一些重要的區別:

  • 要求必須在 參數中包含scope範圍openid
  • 參數 response_type 必須包含 id_token
  • 要求必須包含 nonce 參數。

因此,範例要求看起來會像這樣:

// Line breaks for legibility only

GET https://login.microsoftonline.com/{tenant}/oauth2/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%3a12345
&response_mode=form_post
&scope=openid
&state=12345
&nonce=7362CAEA-9CA5-4B43-9BA3-34D7C303EBA7
參數 類型 說明
租戶 必須的 要求路徑中的 {tenant} 值可用來控制可登入應用程式的人員。 允許的值是租使用者標識碼,例如,8eaef023-2b34-4da1-9baa-8bc8c9d6a490contoso.onmicrosoft.comcommon租用戶無關的令牌
client_id (客戶識別碼) 必須的 當您向 Azure AD 註冊應用程式時,指派給應用程式的應用程式識別碼。 您可以在 Azure 入口網站中找到此專案。 按兩下 [Azure Active Directory],按兩下 [ 應用程式註冊],選擇應用程式,然後在應用程式頁面上找出 [應用程式標識符]。
response_type 必須的 必須包含 id_token 來進行 OpenID Connect 登入。 它也可能包含其他response_types,例如 codetoken
範圍 建議 OpenID Connect 規格需要範圍 openid,其會轉譯為同意 UI 中的「登入」許可權。 v1.0 端點上會忽略這些和其它 OIDC 權限範圍,但對於符合標準的用戶端來說,遵循這些最佳實踐仍然是有益的。
nonce 必須的 包含在要求中的值 (由應用程式所產生),將會包含在所得的 id_token 中來做為宣告。 然後,應用程式可以驗證此值,以減少權杖重播攻擊。 值通常是隨機化、唯一的字串或 GUID,可用來識別要求的來源。
重新導向_URI 建議 應用程式的 redirect_uri,是您的應用程式可以傳送和接收驗證回應的位置。 它必須與您在平台裡註冊的其中一個 `redirect_uris` 完全相符,但必須進行 URL 編碼。 如果漏失,用戶代理會隨機傳送回註冊於應用程式的其中一個重定向 URI。 最大長度為 255 個字節
回應模式 自選 指定應該用來將產生的authorization_code傳送回應用程式的方法。 支援的值為 form_postHTTP 表單張貼fragmentURL 片段。 針對 Web 應用程式,我們建議使用 response_mode=form_post 以確保將令牌最安全的傳輸至您的應用程式。 包含id_token的任何流程預設值為 fragment
狀態 建議 令牌回應中傳回的要求中包含的值。 它可以是你想要的任何內容的字串。 隨機產生的唯一值通常用於 防止跨站台要求偽造攻擊。 此狀態也可用來在驗證要求發生之前,將使用者狀態的相關資訊編碼,例如他們所在的頁面或檢視。
提示 自選 表示必要的使用者互動類型。 目前唯一有效的值為 『login』、'none' 和 'consent'。 prompt=login 會強制使用者在該要求上輸入其認證,而不要進行單一登入。 prompt=none 相反 - 它可確保使用者不會顯示任何互動式提示。 如果無法透過單一登錄以無訊息方式完成要求,端點會傳回錯誤。 prompt=consent 會在使用者登入之後觸發 OAuth 同意對話方塊,要求使用者將許可權授與應用程式。
登入提示 自選 如果您事先知道使用者的使用者名稱,可以用此項目來預先填入使用者登入頁面上的使用者名稱/電子郵件地址欄位。 應用程式通常會在重新驗證期間使用此參數,且已使用 preferred_username 宣告從先前登入擷取用戶名稱。

此時,系統會要求使用者輸入其認證並完成驗證。

範例回應

在使用者通過驗證之後,傳送至 redirect_uri 登入要求中指定的 範例回應看起來可能如下:

POST / HTTP/1.1
Host: localhost:12345
Content-Type: application/x-www-form-urlencoded

id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNB...&state=12345
參數 說明
id_token(驗證令牌) 應用程式要求的 id_token。 您可以使用 id_token 來驗證使用者的身分識別,並與用戶開始會話。
狀態 要求中包含的值,也會在權杖回應中返回。 隨機產生的唯一值通常用於 防止跨站台要求偽造攻擊。 此狀態也可用來在驗證要求發生之前,將使用者狀態的相關資訊編碼,例如他們所在的頁面或檢視。

錯誤回應

錯誤回應可能也會傳送至 redirect_uri ,讓應用程式可以適當地處理:

POST / HTTP/1.1
Host: localhost:12345
Content-Type: application/x-www-form-urlencoded

error=access_denied&error_description=the+user+canceled+the+authentication
參數 說明
錯誤 一個錯誤碼字串,可以用來分類發生的錯誤類型並對錯誤做出回應。
錯誤描述 協助開發人員識別驗證錯誤根本原因的特定錯誤訊息。

授權端點錯誤的錯誤代碼

下表說明各種可能在錯誤回應的 error 參數中傳回的錯誤碼。

錯誤碼 說明 用戶端動作
無效請求 通訊協定錯誤,例如遺漏必要的參數。 修正並重新提交要求。 這是開發錯誤,通常會在初始測試過程中發現。
未授權的客戶端 不允許用戶端應用程式要求授權碼。 這通常是在用戶端應用程式未在 Azure AD 中註冊,或未新增至使用者的 Azure AD 租使用者時發生。 應用程式可以提示使用者指示安裝應用程式,並將其新增至 Azure AD。
拒絕存取 資源擁有者拒絕同意 除非使用者同意,否則用戶端應用程式可以通知使用者無法繼續。
不支援的回應類型 授權伺服器不支援要求中的回應類型。 修正並重新提交要求。 這是開發錯誤,通常會在早期測試期間發現。
伺服器錯誤 伺服器發生非預期的錯誤。 再次嘗試請求。 這些錯誤可能是由暫時性狀況所引起。 用戶端應用程式可能會向使用者說明其回應因暫時錯誤而延遲。
暫時無法使用 伺服器暫時過於忙碌而無法處理要求。 再次嘗試請求。 用戶端應用程式可能會向使用者說明其回應因暫時性狀況而延遲。
無效資源 目標資源無效,因為它不存在、Azure AD 找不到或設定不正確。 這表示資源若存在,則尚未在租用戶中設定。 應用程式可以提示使用者指示安裝應用程式,並將其新增至 Azure AD。

驗證 id_token

只要收到 id_token 就不足以驗證使用者身份,您必須驗證簽章,並根據您的應用程式需求驗證 id_token 中的宣告。 Azure AD 端點會使用 JSON Web 令牌 (JWT) 和公鑰密碼編譯來簽署令牌,並確認它們是否有效。

您可以選擇在用戶端程式代碼中驗證 id_token ,但常見的做法是將 傳送 id_token 至後端伺服器並在那裡執行驗證。

您也可以根據您的情境來驗證其他主張。 一些常見的驗證包括:

  • 確保使用者/組織已註冊應用程式。
  • 確保使用者具備適當的授權/許可權,使用widsroles宣告。
  • 確保已達到特定的驗證強度,例如多因素驗證。

驗證 id_token之後,您就可以開始與用戶進行會話,並使用 中的 id_token 宣告來取得應用程式中使用者的相關信息。 此資訊可用於顯示、記錄、個人化等用途。如需有關id_tokens和宣告的詳細資訊,請閱讀AAD id_tokens

傳送登出要求

當您想要將使用者從應用程式中登出時,僅僅清除應用程式的 Cookie 或結束使用者的會話是不足夠的。 您也必須將使用者重新導向至 end_session_endpoint 以進行註銷。如果您無法這麼做,用戶將能夠在不再次輸入其認證的情況下重新驗證您的應用程式,因為它們會具有與 Azure AD 端點的有效單一登錄會話。

您可以簡單地將使用者轉址至 OpenID Connect 元資料檔案中所列的 end_session_endpoint

GET https://login.microsoftonline.com/common/oauth2/logout?
post_logout_redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F

參數 類型 說明
post_logout_redirect_uri 建議 成功註銷之後,用戶應該重新導向至的URL。此 URL 必須符合應用程式註冊入口網站中為您的應用程式註冊的其中一個重新導向 URI。 如果未包含 post_logout_redirect_uri ,用戶會顯示泛型訊息。

單一登出

當您將使用者重新導向至 end_session_endpoint時,Azure AD 會從瀏覽器清除使用者的工作階段。 不過,使用者可能仍會登入其他使用 Azure AD 進行驗證的應用程式。 若要讓這些應用程式同時註銷使用者,Azure AD 會將 HTTP GET 要求傳送至使用者目前登入之所有應用程式的已註冊 LogoutUrl 。 應用程式必須回應此要求,藉由清除任何可識別使用者的會話並傳回 200 回應。 如果您要在應用程式中支援單一登出,您必須在應用程式的程式碼中實作這類 LogoutUrl 。 您可以從 Azure 入口網站設定 LogoutUrl

  1. 登入 Azure 入口網站
  2. 按兩下頁面右上角的帳戶,選擇您的 Active Directory。
  3. 從左側導覽面板中,選擇 [Azure Active Directory],然後選擇 [ 應用程式註冊 ],然後選取您的應用程式。
  4. 按兩下 [ 設定],然後按兩下 [ 屬性 ],然後尋找 [註銷URL] 文字框。

令牌獲得

許多 Web 應用程式不僅需要登入使用者,而且需要使用 OAuth 代表該使用者存取 Web 服務。 此情境結合 OpenID Connect 用於使用者驗證,同時獲取authorization_code,該authorization_code可透過 OAuth 授權碼流程 來獲得access_tokens

取得存取令牌

若要取得存取令牌,您必須修改上述的登入要求:

// Line breaks for legibility only

GET https://login.microsoftonline.com/{tenant}/oauth2/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e        // Your registered Application ID
&response_type=id_token+code
&redirect_uri=http%3A%2F%2Flocalhost%3a12345          // Your registered Redirect Uri, url encoded
&response_mode=form_post                              // `form_post' or 'fragment'
&scope=openid
&resource=https%3A%2F%2Fservice.contoso.com%2F        // The identifier of the protected resource (web API) that your application needs access to
&state=12345                                          // Any value, provided by your app
&nonce=678910                                         // Any value, provided by your app

藉由在要求中包含許可權範圍並使用 response_type=code+id_tokenauthorize 端點可確保使用者已同意查詢參數中所 scope 指出的許可權,並傳回應用程式授權碼以交換存取令牌。

成功回應

使用 response_mode=form_post傳送至 redirect_uri 的成功回應如下所示:

POST /myapp/ HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNB...&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...&state=12345
參數 說明
id_token(驗證令牌) id_token 是應用程式要求的。 您可以使用 id_token 來驗證使用者的身分識別,並與用戶開始會話。
程式碼 應用程式所要求的授權碼。 應用程式可以使用授權碼來要求目標資源的存取權杖。 授權碼的有效期很短,通常在大約 10 分鐘後會到期。
狀態 如果要求中包含 state 參數,則回應中應該會出現相同的值。 應用程式必須確認要求與回覆中的狀態值完全相同。

錯誤回應

錯誤回應可能也會傳送至 redirect_uri ,讓應用程式可以適當地處理:

POST /myapp/ HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded

error=access_denied&error_description=the+user+canceled+the+authentication
參數 說明
錯誤 一種錯誤代碼字串,可用於分類發生的錯誤類型,也可用於對錯誤作出反應。
錯誤描述 協助開發人員識別驗證錯誤根本原因的特定錯誤訊息。

如需可能錯誤碼及其建議客戶端動作的描述,請參閱 授權端點錯誤的錯誤碼

一旦您取得授權 codeid_token,您就可以登入使用者,並代表他們取得 存取令牌 。 若要登入使用者,您必須按照上述確切說明驗證id_token。 若要取得存取令牌,您可以遵循 OAuth 程式代碼流程檔的一節中所述的步驟。

後續步驟