第三方登入系列文章的第四篇「在 ASP.NET Core 整合 Microsoft 做第三方登入」,Microsoft 是老牌的大廠,旗下的 Windows、Office、Azure、...等產品,都已經融入了我們的生活當中,Microsoft 也有提供 OAuth 2.0 授權平台,整個整合的過程,就記錄在這篇文章當中。
其他的第三方登入解決方案可以參考下面的連結:
- 在 ASP.NET Core 整合 LINE Login 做為網站的第三方登入
- 在 ASP.NET Core 整合 Facebook 做為網站的第三方登入
- 在 ASP.NET Core 整合 Google 做為網站的第三方登入
- 在 ASP.NET Core 整合 GitHub 做為網站的第三方登入
- 在 ASP.NET Core 整合 Twitter 做為網站的第三方登入
註冊應用程式
首先,先讓 Microsoft 認識我們的應用程式,我們到 Azure 入口網站應用程式註冊的頁面中,註冊我們的應用程式。
點擊「新增註冊
」,填入我們想要的「名稱
」,下面的「支援的帳戶類型
」選擇任何組織目錄中的帳戶 (任何 Azure AD 目錄 - 多租用戶) 和個人 Microsoft 帳戶 (例如 Skype、Xbox)
,這個選項所支援的 Microsoft 帳戶類型是最廣的,接著「重新導向 URI
」如果我們已經知道 Web Api 的網址,可以先填入,不知道也沒關係,之後可以回來修改,最後點擊「註冊
」。


應用程式註冊完成後,在「概觀
」的頁籤當中,我們會需要應用程式 (用戶端) 識別碼
這個資訊,請複製下來備用。

除此之外,還需要「用戶端密碼
」,在應用程式的管理頁面中,點選「憑證及秘密
」,點擊「新增用戶端密碼
」,輸入「描述
」後,點擊「新增
」。

用戶端密碼新增完成後,將「值
」複製下來備用。

比起其他平台,Microsoft 的應用程式註冊流程算是很簡潔,一個按鈕、兩三個輸入框,就能註冊成功了,節省不少整合的時間。
準備重新導向 URI
往下進入程式開發的環節,使用者完成授權後,Microsoft 會將 code
回傳到我們設定的重新導向 URI
,我們要拿著這個 code 發送 POST 去跟 Microsoft 交換 Access Token
,交換 Access Token 的 URL 及參數如下:
AccessTokenUrl
:https://login.microsoftonline.com/common/oauth2/v2.0/tokengrant_type
:填入 "authorization_code"code
:即我們拿到的 coderedirect_uri
:即重新導向 URIclient_id
:即應用程式 (用戶端) 識別碼client_secret
:即用戶端密碼
重新導向 URI 的程式碼如下:
[HttpGet("callback")]
public async Task<IActionResult> Callback()
{
if (!this.Request.Query.TryGetValue("code", out var code))
{
return this.StatusCode(400);
}
var (accessToken, idToken) = await this.ExchangeAccessToken(code);
if (accessToken == null)
{
return this.StatusCode(400);
}
// TODO: Save AccessToken and IdToken
// TODO: User Login
return this.Redirect("/");
}
private async Task<(string, string)> ExchangeAccessToken(string code)
{
var client = this.httpClientFactory.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Post, "AccessTokenUrl");
request.Content = new FormUrlEncodedContent(
new Dictionary<string, string>
{
["grant_type"] = "authorization_code",
["code"] = code,
["redirect_uri"] = "RedirectURI",
["client_id"] = "ClientId",
["client_secret"] = "ClientSecret"
});
var response = await client.SendAsync(request);
if (response.StatusCode != HttpStatusCode.OK) return (null, null);
var content = await response.Content.ReadAsStringAsync();
var result = JsonNode.Parse(content);
return (result["access_token"].GetValue<string>(), result["id_token"].GetValue<string>());
}
授權網址
最後我們要來兜授權網址
,使用者點擊授權網址之後,就開始登入的流程,而 Microsoft 的授權網址是 https://login.microsoftonline.com/common/oauth2/v2.0/authorize
,所需參數如下:
response_type
:填入 "code"client_id
:即應用程式 (用戶端) 識別碼redirect_uri
:即重新導向 URIstate
:隨機產生的一段唯一的字串,主要是可以用來避免 CSRF(Cross Site Request Forgery)。scope
:想請使用者授權給我們的資料範圍
由上述參數所兜出來的網址如下:
登入的流程大致如下圖:

當使用者瀏覽授權網址之後,就會導到 Microsoft 的登入授權畫面,使用者授權後,導回到我們系統,拿到使用者資料就算是整合成功了。


整合了這麼些個 OAuth 2.0 的平台之後,相較於其他平台,Microsoft 的文件是我認為相對清楚的,取得所需要的資訊不用翻箱倒櫃,整個整合起來沒有花太多時間,一路上算是順暢,以上,整合 Microsoft 第三方登入的步驟就分享給大家,希望大家都能整合成功。