[MDP.NetCore] 使用AzureAD+服務主體,快速建立兩個服務之間的Service身分認證
MDP.AspNetCore.Authentication.AzureAD.Services for Service Principal
MDP.AspNetCore.Authentication.AzureAD.Services擴充ASP.NET Core既有的身分驗證,加入AzureAD提供的Service身分驗證功能。開發人員可以透過Config設定,掛載在專案裡使用的Service身分驗證,用以驗證Azure裡的服務主體(Service Principal)。
說明文件:https://clark159.github.io/MDP.AspNetCore.Authentication/
程式源碼:https://github.com/Clark159/MDP.AspNetCore.Authentication/
特別說明:本篇範例的API客戶端、API服務端,兩者皆可以在Azure環境之外部署使用。
運作流程
MDP.AspNetCore.Authentication.AzureAD.Services使用AzureAD提供的OAuth服務,透過Client Credentials流程來進行Service身分驗證。下列兩個運作流程,說明AzureAD的憑證發放流程、服務驗證流程。(內容為簡化說明,完整細節可參考AzureAD文件)
憑證發放

1.開發人員至AzureAD,建立API Client的應用程式註冊。
2.開發人員從AzureAD,取得API Client的身分憑證,內容包含:TenantId、ClientId、ClientSecret。
3.開發人員將API Client的身分憑證,設定在API Client應用程式的Config參數。
4.開發人員至AzureAD,建立API Provider的應用程式註冊。
5.開發人員從AzureAD,取得API Provider的身分憑證,內容包含:TenantId、ClientId。(沒有ClientSecret)
6.開發人員將API Provider的身分憑證,設定在API Provider應用程式的Config參數。
服務驗證

1.使用者開啟API Client提供的URL。
2.API Client從Config參數,取得API Client的身分憑證發送給AzureAD,內容包含:TenantId、ClientId、ClientSecret。
3.AzureAD依照API Client的身分憑證,使用內建的公私鑰加密機制,回傳代表API Client的AccessToken。
4.API Client調用API,並且將AccessToken放置在API Request封包的Header。
5.API Provider從Config參數,取得API Provider的身分憑證發送給AzureAD,內容包含:TenantId、ClientId。(沒有ClientSecret)
6.AzureAD依照API Provider的身分憑證,使用內建的公私鑰管理機制,回傳可以驗證AccessToken的公鑰(Public Key)。
7.API Provider使用Public Key驗證AccessToken簽章,確認合法就依照系統邏輯回傳API Response。(不合法回傳401 Unauthorized)
8.API Client依照API Response,回傳Page給使用者。
模組使用-API服務端(API Provider)
申請服務
MDP.AspNetCore.Authentication.AzureAD.Services使用AzureAD提供的OAuth服務,透過Client Credentials流程來進行Service身分驗證。依照下列操作步驟,即可申請AzureAD提供給API服務端(API Provider)的身分憑證。
1.註冊並登入Microsoft Azure Portal。於首頁左上角的選單裡,點擊應用程式註冊後,進入應用程式註冊頁面。

2.於應用程式註冊頁面,點擊新增註冊按鈕,依照頁面提示建立一個Application。


3.於Application頁面,取得「目錄 (租用戶) 識別碼」、「應用程式 (用戶端) 識別碼」。接著點擊新增應用程式識別碼 URI按鈕,進入公開API頁面,然後點擊新增,依照頁面提示建立並取得一個「應用程式識別碼 URI」。




4.於Application頁面,點擊左側選單的應用程式角色,進入應用程式角色頁面。然後點擊建立應用程式角色,依照頁面提示建立並取得一個「應用程式角色」。




加入專案
申請服務完成之後,就可以開始建立專案並且加入模組。MDP.AspNetCore.Authentication.AzureAD.Services預設獨立在MDP.Net專案範本外,依照下列操作步驟,即可建立加入MDP.AspNetCore.Authentication.AzureAD.Services的專案。
- 在命令提示字元輸入下列指令,使用MDP.Net專案範本建立專案。
dotnet new install MDP.WebApp
dotnet new MDP.WebApp -n ApiProvider
- 使用Visual Studio開啟專案。在專案裡使用NuGet套件管理員,新增下列NuGet套件。
MDP.AspNetCore.Authentication.AzureAD.Services
設定參數
建立包含MDP.AspNetCore.Authentication.AzureAD.Services的專案之後,就可以透過Config設定,掛載在專案裡使用的Service身分驗證。
// Config設定
{
"Authentication": {
"AzureAD.Services": {
"TenantId": "xxxxx",
"ClientId": "xxxxx"
}
}
}
- 命名空間:Authentication
- 掛載的身分驗證模組:AzureAD.Services
- API服務端的租戶編號:TenantId="xxxxx"。(xxxxx填入目錄 (租用戶) 識別碼)
- API服務端的客戶編號:ClientId="xxxxx"。(xxxxx填入應用程式 (用戶端) 識別碼)
模組使用-API客戶端(API Client)
申請服務(API Client)
MDP.AspNetCore.Authentication.AzureAD.Services使用AzureAD提供的OAuth服務,透過Client Credentials流程來進行Service身分驗證。依照下列操作步驟,即可申請AzureAD提供給API客戶端(API Client)的身分憑證。
1.註冊並登入Microsoft Azure Portal。於首頁左上角的選單裡,點擊應用程式註冊後,進入應用程式註冊頁面。

2.於應用程式註冊頁面,點擊新增註冊按鈕,依照頁面提示建立一個Application。


3.於Application頁面,取得「目錄 (租用戶) 識別碼」、「應用程式 (用戶端) 識別碼」。接著點擊新增憑證或祕密按鈕,進入憑證及祕密頁面,然後點擊新增用戶端密碼,依照頁面提示建立並取得一個「用戶端密碼」。(記得要取「值」的內容)



4.於Application頁面,點擊左側選單的API權限,進入API權限頁面。然後點擊新增權限,依照頁面提示,新增「應用程式角色」給應用程式。




5.停留於API權限頁面,點擊代表xxxx授予管理員同意按鈕,依照頁面提示授予API權限。(xxxx為目錄名稱)



加入專案
申請服務完成之後,就可以開始建立專案並且加入模組。Azure.Identity預設獨立在MDP.Net專案範本外,依照下列操作步驟,即可建立加入Azure.Identity的專案。
- 在命令提示字元輸入下列指令,使用MDP.Net專案範本建立專案。
dotnet new install MDP.WebApp
dotnet new MDP.WebApp -n ApiClient
- 使用Visual Studio開啟專案。在專案裡使用NuGet套件管理員,新增下列NuGet套件。
Azure.Identity
使用憑證
建立包含Azure.Identity的專案之後,就可以在程式碼裡使用憑證,建立代表API客戶端身分的AccessToken,用來通過API服務端的Service身分驗證。
// 參數設定
var azureCredential = new ClientSecretCredential
(
tenantId: "xxxxx",
clientId: "xxxxx",
clientSecret: "xxxxx"
);
var apiProviderURI= "api://xxxxx";
var apiProviderEndpoint= "https://localhost:7146/Home/Index";
- API客戶端的租戶編號:tenantId: "xxxxx"。(xxxxx填入目錄 (租用戶) 識別碼)
- API客戶端的客戶編號:clientId: "xxxxx"。(xxxxx填入應用程式 (用戶端) 識別碼)
- API客戶端的客戶密碼:clientSecret: "xxxxx"。(xxxxx填入用戶端密碼)
- API服務端的應用程式識別碼URI: apiProviderURI= "api://xxxxx"。(xxxxx填入應用程式識別碼URI)
- API服務端的API服務端點: apiProviderEndpoint= "https://localhost:7146/Home/Index"。
// 建立AccessToken
var accessToken = (await azureCredential.GetTokenAsync(new Azure.Core.TokenRequestContext(new string[] { $"{apiProviderURI}/.default" }), default)).Token;
// 呼叫API服務端點
var responseContent = string.Empty;
using (var httpClient = new HttpClient())
{
// Headers
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
// Send
var response = await httpClient.GetAsync(apiProviderEndpoint);
responseContent = await response?.Content?.ReadAsStringAsync();
}
模組範例
使用AzureAD提供的Service身分驗證功能,進行 Service to Service 之間的身分驗證,是開發系統時常見的功能需求。本篇範例協助開發人員使用MDP.AspNetCore.Authentication.AzureAD.Services,逐步完成必要的設計和實作。
範例下載:ApiClient.zip
範例下載:ApiProvider.zip
特別說明:本篇範例的API客戶端、API服務端,兩者皆可以在Azure環境之外部署使用。
建立API服務端(API Provider)
1.開啟命令提示字元,輸入下列指令。用以安裝MDP.WebApp範本、並且建立一個名為ApiProvider的Web站台。
dotnet new install MDP.WebApp
dotnet new MDP.WebApp -n ApiProvider
2.使用Visual Studio開啟ApiProvider專案,在專案裡用NuGet套件管理員新增下列NuGet套件。
MDP.AspNetCore.Authentication.AzureAD.Services
3.依照模組使用-API服務端(API Provider)-申請服務的步驟流程,申請AzureAD提供的OAuth服務,並取得「目錄 (租用戶) 識別碼」、「應用程式 (用戶端) 識別碼」、「應用程式識別碼 URI」。

4.於專案內改寫appsettings.json,填入「目錄 (租用戶) 識別碼」、「應用程式 (用戶端) 識別碼」,用以掛載Service身分驗證。
{
"Authentication": {
"AzureAD.Services": {
"TenantId": "xxxxx", // API Provider-目錄 (租用戶) 識別碼
"ClientId": "xxxxx" // API Provider-應用程式 (用戶端) 識別碼
}
}
}
5.改寫專案內的Controllers\HomeController.cs,提供一個必須通過身分驗證才能使用的\Home\Index API服務端點。
using MDP.AspNetCore.Authentication.AzureAD.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using System.Security.Claims;
namespace ApiProvider
{
public class HomeController : Controller
{
// Methods
[Authorize]
public string Index()
{
// ClaimsIdentity
var claimsIdentity = this.User.Identity as ClaimsIdentity;
if (claimsIdentity == null) throw new InvalidOperationException($"{nameof(claimsIdentity)}=null");
Console.WriteLine($"this.User.AuthenticationType = {claimsIdentity.AuthenticationType}");
Console.WriteLine($"this.User.TenantId = {claimsIdentity.FindFirst(AzureServicesAuthenticationClaimTypes.TenantId)?.Value}");
Console.WriteLine($"this.User.ClientId = {claimsIdentity.FindFirst(AzureServicesAuthenticationClaimTypes.ClientId)?.Value}");
Console.WriteLine($"this.User.Roles = {String.Join(",", claimsIdentity.FindAll(System.Security.Claims.ClaimTypes.Role).Select(o => o.Value))}");
Console.WriteLine();
// Return
return "Hello World";
}
}
}
建立API客戶端(API Client)
1.開啟命令提示字元,輸入下列指令。用以安裝MDP.WebApp範本、並且建立一個名為ApiClient的Web站台。
dotnet new install MDP.WebApp
dotnet new MDP.WebApp -n ApiClient
2.使用Visual Studio開啟ApiClient專案,在專案裡用NuGet套件管理員新增下列NuGet套件。
Azure.Identity
3.依照模組使用-API客戶端(API Client)-申請服務的步驟流程,申請AzureAD提供的OAuth服務,並取得「目錄 (租用戶) 識別碼」、「應用程式 (用戶端) 識別碼」、「用戶端密碼」。

4.改寫專案內的Controllers\HomeController.cs、Views\Home\Index.cshtml,提供Home頁面。並於Home頁面,使用憑證,建立代表API客戶端身分的AccessToken,用來通過API服務端的Service身分驗證後,取得資料顯示於頁面。
using Azure.Identity;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace ApiClient
{
public class HomeController : Controller
{
// Methods
public async Task<ActionResult> Index()
{
// Variables
var azureCredential = new ClientSecretCredential
(
tenantId: "xxxxx", // API Client-目錄 (租用戶) 識別碼
clientId: "xxxxx", // API Client-應用程式 (用戶端) 識別碼
clientSecret: "xxxxx" // API Client-用戶端密碼
);
var apiProviderURI = "api://xxxxx"; // API Provider-「應用程式識別碼 URI」
var apiProviderEndpoint = "https://localhost:7146/Home/Index"; // API Provider-API服務端點
// AccessToken
var accessToken = (await azureCredential.GetTokenAsync(new Azure.Core.TokenRequestContext(new string[] { $"{apiProviderURI}/.default" }), default)).Token;
if (string.IsNullOrEmpty(accessToken) == true) throw new InvalidOperationException($"{nameof(accessToken)}=null");
// Call API
var responseContent = string.Empty;
using (var httpClient = new HttpClient())
{
// Headers
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
// Send
var response = await httpClient.GetAsync(apiProviderEndpoint);
responseContent = await response?.Content?.ReadAsStringAsync();
}
if (string.IsNullOrEmpty(responseContent) == true) throw new InvalidOperationException($"{nameof(responseContent)}=null");
// ViewBag
this.ViewBag.Message = responseContent;
// Return
return View();
}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>ApiClient</title>
</head>
<body>
<!--Title-->
<h2>ApiClient</h2>
<hr />
<!--Message-->
<h3>@ViewBag.Message</h3>
</body>
</html>
範例執行
1.使用Visual Studio開啟ApiProvider專案並執行。
2.使用Visual Studio開啟ApiClient專案並執行。
3.於ApiClient專案,執行所開啟的Browser視窗內,可以看到系統畫面進入到Home頁面,並且顯示API服務端回傳的”Hello World”。

4.於ApiProvider專案,執行所開啟的Console視窗內,可以看到通過Service身分驗證的API客戶端身分資料(Controller.User屬性)。

[MDP.NetCore] 使用AzureAD+服務主體,快速建立兩個服務之間的Service身分認證的更多相关文章
- GoldenGate 传统抽取进程随 DataGuard 主备快速切换的方案(ADG 模式)
环境描述: 1.节点描述 节点 IP 节点描述 11.6.76.221 GG 抽取端 / DG 节点,数据库版本号为 Oracle-11.2.0.3,与 11.6.76.222 组成 DataGuar ...
- 优步司机如何联系客服?uber客服渠道,Uber优步司机客服渠道
预约客服导航 为了更好的快速.有效地解决您的疑问,Uber优步从今日起开通了在线客服平台.如果您通过司机服务/常见问题没有找到您需要的答案,您可以通过点击下方的“进入在线客服平台”与我们的工作人员在线 ...
- 如何在DCS管理控制台将两个Redis主备实例建立全球灾备。
华为云分布式缓存服务DCS,具有强大的功能,现在小编教大家如何在DCS管理控制台将两个Redis主备实例建立全球灾备. 建立全球灾备,会对主实例和备实例进行升级,实例进程会重启,连接会中断.同时备实例 ...
- 厌倦了“正在输入…”的客服对话,是时候pick视频客服了
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云视频发表于云+社区专栏 关注公众号"腾讯云视频",一键获取 技术干货 | 优惠活动 | 视频方案 什么?! ...
- AI人工客服开发 小程序智能客服 智能客服微信小程序 智能客服系统怎么做 如何设计智能客服系统
今天我们就来给大家分享下如何做 小程序的智能客服问答系统. 首先请确保你的小程序在线客服已经开通使用,并使用代码自己对接好了,将客户的提问自动做了拦截,拦截到了你自己开发的接口上. 做好了拦截以后,我 ...
- 超级详细Tcpdump 的用法
1.抓取回环网口的包:tcpdump -i lo 2.防止包截断:tcpdump -s0 3.以数字显示主机及端口:tcpdump -n 第一种是关于类型的关键字,主要包括host,net,port, ...
- Asp.net attributes collection
<?xml version="1.0" encoding="utf-8"?><root> <ContralNames> ...
- 鸟哥的linux私房菜---非常好的linux基础网址【转】
转自:http://linux.vbird.org/linux_basic/0320bash.php 在 Linux 的環境下,如果你不懂 bash 是什麼,那麼其他的東西就不用學了!因為前面幾章我們 ...
- tcpdump抓包分析具体解释
說實在的,對於 tcpdump 這個軟體來說,你甚至能够說這個軟體其實就是個駭客軟體, 因為他不但能够分析封包的流向,連封包的內容也能够進行『監聽』, 假设你使用的傳輸資料是明碼的話,不得了,在 ro ...
- CentOS7安全设置 yum-cron系统自动更新,firewalld防火墙简单使用
PermitRootLogin nosystemctl restart sshd.service; yum -y install firewalld; systemctl start firewall ...
随机推荐
- Axios向后段请求数据GET POST两种方法的不同之处
GET请求 向后端请求时,通过URL向后端传递参数 axios({ url:'http://127.0.0.1:9000/get-user-list/', type:'json', //GET方法携带 ...
- pandas 字典创建Dataframe
所有的ndarrays必须具有相同的长度.如果传递了索引(index),则索引的长度应等于数组的长度.如果没有传递索引,则默认情况下,索引为range(n),其中n为数组长度. import pand ...
- 新一代开源流数据湖平台Apache Paimon入门实操-下
@ 目录 实战 写表 插入和覆盖数据 更新数据 删除数据 Merge Into 查询表 批量查询 时间旅行 批量增量查询 流式查询 时间旅行 ConsumerID 查询优化 系统表 表指定系统表 分区 ...
- .NET 8 发布的最后一个预览版Preview 7, 下个月发布RC
微软在2023年8月9日 发布了.NET 8 Preview 7[1],这是它在11月14日 RTM 之前进入发布候选阶段之前的最后预览版. 该预览版也于也与 VS 2022 v17.7 版本一起发布 ...
- 论文解读(BSFDA)《Black-box Source-free Domain Adaptation via Two-stage Knowledge Distillation》
Note:[ wechat:Y466551 | 可加勿骚扰,付费咨询 ] 论文信息 论文标题:Black-box Source-free Domain Adaptation via Two-stage ...
- What...MiniGPT-4居然开源了,提前感受 GPT-4 的图像对话能力!
说在前面的话: 一个月前,OpenAI向外界展示了GPT-4如何通过手绘草图直接生成网站,令当时的观众瞠目结舌. 在GPT-4发布会之后,相信大家对ChatGPT的对话能力已有所了解.圈内的朋友们应该 ...
- SQL Server用户的设置与授权
SQL Server用户的设置与授权 SSMS 登陆方式有两种,一是直接使用Windows身份验证,二是SQL Server身份验证.使用SQL Server用户设置与授权不仅可以将不同的数据库开放给 ...
- @Validated指定校验顺序
在Java中,使用@NotNull注解时,可以指定多个参数的顺序.为了指定顺序,你可以使用@GroupSequence注解. 首先,为每个需要校验的参数定义一个接口,并在接口上添加@GroupSequ ...
- Record - Dec. 1st, 2020 - Exam. REC
Prob. 1 Desc. & Link. 行走的形式是比较自由的,因为只要走到了最优答案处就可以不管了,所以不需要考虑游戏的结束. 考虑二分答案. 然后预处理出每个节点到 \(s\)(另一棵 ...
- CAP项目集成带身份和证书验证的MongoDB
大家好,我是Edison. 最近,在使用CAP事件总线时,碰到了这样一个需求:微服务采用的是MongoDB,而且还是带身份验证 和 SSL根证书验证的.由于目前网上能找到的资料,都是不带身份验证的Mo ...