mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-03-12 21:22:57 -07:00
Translated ['', 'src/pentesting-cloud/azure-security/az-basic-informatio
This commit is contained in:
@@ -1,100 +1,100 @@
|
||||
# Az - Tokens & Public Applications
|
||||
# Az - 令牌与公共应用程序
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## 基本信息
|
||||
|
||||
Entra ID 是微软基于云的身份和访问管理 (IAM) 平台,作为 Microsoft 365 和 Azure Resource Manager 等服务的基础认证和授权系统。Azure AD 实现了 OAuth 2.0 授权框架和 OpenID Connect (OIDC) 认证协议,以管理对资源的访问。
|
||||
Entra ID 是 Microsoft 的云端身份与访问管理 (IAM) 平台,作为 Microsoft 365 和 Azure Resource Manager 等服务的基础身份验证和授权系统。Azure AD 实现了 OAuth 2.0 授权框架和 OpenID Connect (OIDC) 身份验证协议来管理对资源的访问。
|
||||
|
||||
### OAuth
|
||||
|
||||
**OAuth 2.0 的关键参与者:**
|
||||
|
||||
1. **资源服务器 (RS):** 保护资源所有者拥有的资源。
|
||||
2. **资源所有者 (RO):** 通常是拥有受保护资源的最终用户。
|
||||
3. **客户端应用程序 (CA):** 代表资源所有者请求访问资源的应用程序。
|
||||
4. **授权服务器 (AS):** 在验证和授权客户端应用程序后向其发放访问令牌。
|
||||
1. **Resource Server (RS):** 保护资源所有者拥有的资源。
|
||||
2. **Resource Owner (RO):** 通常是拥有受保护资源的终端用户。
|
||||
3. **Client Application (CA):** 代表资源所有者请求访问资源的应用。
|
||||
4. **Authorization Server (AS):** 在认证并授权客户端应用后向其颁发 access tokens。
|
||||
|
||||
**范围和同意:**
|
||||
**Scopes 与 同意:**
|
||||
|
||||
- **范围:** 在资源服务器上定义的细粒度权限,指定访问级别。
|
||||
- **同意:** 资源所有者授予客户端应用程序访问特定范围资源的权限的过程。
|
||||
- **Scopes:** 在资源服务器上定义的细粒度权限,用于指定访问级别。
|
||||
- **Consent:** 资源所有者授予客户端应用以特定 scopes 访问资源的过程。
|
||||
|
||||
**Microsoft 365 集成:**
|
||||
|
||||
- Microsoft 365 利用 Azure AD 进行 IAM,并由多个“第一方”OAuth 应用程序组成。
|
||||
- 这些应用程序深度集成,通常具有相互依赖的服务关系。
|
||||
- 为了简化用户体验并保持功能,微软对这些第一方应用程序授予“隐含同意”或“预先同意”。
|
||||
- **隐含同意:** 某些应用程序在没有明确用户或管理员批准的情况下**自动获得对特定范围的访问权限**。
|
||||
- 这些预先同意的范围通常对用户和管理员都是隐藏的,使其在标准管理界面中不太可见。
|
||||
- Microsoft 365 使用 Azure AD 作为 IAM,并由多个 “first-party” OAuth 应用组成。
|
||||
- 这些应用深度集成,通常具有相互依赖的服务关系。
|
||||
- 为简化用户体验并维持功能,Microsoft 会对这些 first-party 应用授予“implied consent”或“pre-consent”。
|
||||
- **Implied Consent:** 某些应用会被自动**授予对特定 scopes 的访问权限,而无需明确的用户或管理员批准**。
|
||||
- 这些预先同意的 scopes 通常对用户和管理员都隐藏,使其在标准管理界面中不易被看到。
|
||||
|
||||
**客户端应用程序类型:**
|
||||
**客户端应用类型:**
|
||||
|
||||
1. **机密客户端:**
|
||||
- 拥有自己的凭据(例如,密码或证书)。
|
||||
- 可以**安全地向授权服务器进行身份验证**。
|
||||
2. **公共客户端:**
|
||||
- 没有唯一凭据。
|
||||
- 不能安全地向授权服务器进行身份验证。
|
||||
- **安全隐患:** 攻击者可以在请求令牌时冒充公共客户端应用程序,因为授权服务器没有机制来验证应用程序的合法性。
|
||||
1. **Confidential Clients:**
|
||||
- 拥有自己的凭据(例如密码或证书)。
|
||||
- 可以**安全地对授权服务器进行自身认证**。
|
||||
2. **Public Clients:**
|
||||
- 没有唯一的凭据。
|
||||
- 无法向授权服务器进行安全认证。
|
||||
- **安全含义:** 当请求 tokens 时,攻击者可以冒充 public client 应用,因为授权服务器无法验证该应用的合法性。
|
||||
|
||||
## 认证令牌
|
||||
## 身份验证令牌
|
||||
|
||||
在 OIDC 中使用**三种类型的令牌**:
|
||||
OIDC 中使用的**三种令牌**:
|
||||
|
||||
- [**访问令牌**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** 客户端将此令牌呈现给资源服务器以**访问资源**。它只能用于特定的用户、客户端和资源组合,并且**在到期之前无法被撤销** - 默认情况下为 1 小时。
|
||||
- **ID 令牌**:客户端从**授权服务器**接收此**令牌**。它包含有关用户的基本信息。它**绑定到特定的用户和客户端组合**。
|
||||
- **刷新令牌**:与访问令牌一起提供给客户端。用于**获取新的访问和 ID 令牌**。它绑定到特定的用户和客户端组合,并且可以被撤销。默认过期时间为**90 天**(对于不活动的刷新令牌)和**活动令牌没有过期**(可以从刷新令牌获取新的刷新令牌)。
|
||||
- 刷新令牌应与**`aud`**、某些**范围**和**租户**相关联,并且只能为该 aud、范围(且不更多)和租户生成访问令牌。然而,这在**FOCI 应用程序令牌**中并非如此。
|
||||
- 刷新令牌是加密的,只有微软可以解密它。
|
||||
- 获取新的刷新令牌不会撤销先前的刷新令牌。
|
||||
- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** 客户端向资源服务器出示此 token 以**访问资源**。它只能用于特定的用户、客户端和资源组合,并且在过期之前**无法被撤销**——默认有效期为 1 小时。
|
||||
- **ID Tokens:** 客户端从授权服务器接收的**token**。它包含关于用户的基本信息。它**绑定到特定的用户与客户端组合**。
|
||||
- **Refresh Tokens:** 与 access token 一起提供给客户端。用于**获取新的 access 和 ID tokens**。它绑定到特定的用户与客户端组合并且可以被撤销。默认过期为**90 天**(对于不活跃的 refresh tokens),并且**活动 token 默认不失效**(通过 refresh token 可以获取新的 refresh tokens)。
|
||||
- 一个 refresh token 应该绑定到一个 **`aud`**、一些 **scopes** 和一个 **tenant**,并且它应只能为该 aud、这些 scopes(且不能超出)和该 tenant 生成 access tokens。然而,**FOCI applications tokens** 并不遵循该约束。
|
||||
- refresh token 是加密的,只有 Microsoft 能解密它。
|
||||
- 获取新的 refresh token 并不会撤销之前的 refresh token。
|
||||
|
||||
> [!WARNING]
|
||||
> **条件访问**的信息存储在**JWT**中。因此,如果您从**允许的 IP 地址**请求**令牌**,该**IP**将被**存储**在令牌中,然后您可以从**不允许的 IP 访问资源**使用该令牌。
|
||||
> 有关 **conditional access** 的信息**存储**在 **JWT** 内。因此,如果你从一个**被允许的 IP 地址**请求了该**token**,该**IP** 会被**存储**在 token 中,然后你可以从一个**未被允许的 IP**使用该 token 来访问资源。
|
||||
|
||||
### 访问令牌 "aud"
|
||||
### Access Tokens "aud"
|
||||
|
||||
“aud”字段中指示的字段是用于执行登录的**资源服务器**(应用程序)。
|
||||
"aud" 字段中指示的值是用于执行登录的**resource server**(即应用)。
|
||||
|
||||
命令 `az account get-access-token --resource-type [...]` 支持以下类型,每种类型将在结果访问令牌中添加特定的“aud”:
|
||||
命令 `az account get-access-token --resource-type [...]` 支持以下类型,每种类型都会在生成的 access token 中添加特定的 "aud":
|
||||
|
||||
> [!CAUTION]
|
||||
> 请注意,以下仅是 `az account get-access-token` 支持的 API,但还有更多。
|
||||
> 注意,以下仅是 `az account get-access-token` 支持的部分 API,但并不止这些。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>aud 示例</summary>
|
||||
|
||||
- **aad-graph (Azure Active Directory Graph API)**:用于访问遗留的 Azure AD Graph API(已弃用),允许应用程序读取和写入 Azure Active Directory (Azure AD) 中的目录数据。
|
||||
- **aad-graph (Azure Active Directory Graph API)**:用于访问遗留的 Azure AD Graph API(已弃用),允许应用读取和写入 Azure Active Directory (Azure AD) 中的目录数据。
|
||||
- `https://graph.windows.net/`
|
||||
|
||||
* **arm (Azure Resource Manager)**:用于通过 Azure Resource Manager API 管理 Azure 资源。这包括创建、更新和删除虚拟机、存储帐户等资源的操作。
|
||||
* **arm (Azure Resource Manager)**:用于通过 Azure Resource Manager API 管理 Azure 资源,包括创建、更新和删除虚拟机、存储帐户等资源。
|
||||
- `https://management.core.windows.net/ or https://management.azure.com/`
|
||||
|
||||
- **batch (Azure Batch Services)**:用于访问 Azure Batch,这是一项服务,可在云中高效地启用大规模并行和高性能计算应用程序。
|
||||
- **batch (Azure Batch Services)**:用于访问 Azure Batch,该服务支持在云中高效运行大规模并行和高性能计算应用。
|
||||
- `https://batch.core.windows.net/`
|
||||
|
||||
* **data-lake (Azure Data Lake Storage)**:用于与 Azure Data Lake Storage Gen1 交互,这是一项可扩展的数据存储和分析服务。
|
||||
* **data-lake (Azure Data Lake Storage)**:用于与 Azure Data Lake Storage Gen1 交互,这是一个可扩展的数据存储与分析服务。
|
||||
- `https://datalake.azure.net/`
|
||||
|
||||
- **media (Azure Media Services)**:用于访问 Azure Media Services,提供基于云的视频和音频内容处理和交付服务。
|
||||
- **media (Azure Media Services)**:用于访问 Azure Media Services,为音视频内容提供云端的媒体处理和交付服务。
|
||||
- `https://rest.media.azure.net`
|
||||
|
||||
* **ms-graph (Microsoft Graph API)**:用于访问 Microsoft Graph API,这是 Microsoft 365 服务数据的统一端点。它允许您访问 Azure AD、Office 365、企业移动性和安全服务等服务的数据和见解。
|
||||
* **ms-graph (Microsoft Graph API)**:用于访问 Microsoft Graph API,这是 Microsoft 365 服务数据的统一端点。它允许你访问来自 Azure AD、Office 365、企业移动性及安全服务等的数据信息。
|
||||
- `https://graph.microsoft.com`
|
||||
|
||||
- **oss-rdbms (Azure Open Source Relational Databases)**:用于访问 Azure 数据库服务,支持开源关系数据库引擎,如 MySQL、PostgreSQL 和 MariaDB。
|
||||
- **oss-rdbms (Azure Open Source Relational Databases)**:用于访问 Azure 的开源关系数据库服务,如 MySQL、PostgreSQL 和 MariaDB。
|
||||
- `https://ossrdbms-aad.database.windows.net`
|
||||
|
||||
</details>
|
||||
|
||||
### 访问令牌范围 "scp"
|
||||
### Access Tokens Scopes "scp"
|
||||
|
||||
访问令牌的范围存储在访问令牌 JWT 内的 scp 键中。这些范围定义了访问令牌可以访问的内容。
|
||||
access token 的 scope 存储在 access token JWT 的 scp 键中。这些 scopes 定义了 access token 可以访问的内容。
|
||||
|
||||
如果 JWT 被允许联系特定 API,但**没有范围**来执行请求的操作,它**将无法使用该 JWT 执行该操作**。
|
||||
如果一个 JWT 被允许联系某个特定 API,但**没有执行所请求操作的 scope**,那么该 JWT **将无法执行该操作**。
|
||||
|
||||
### 获取刷新和访问令牌示例
|
||||
### 获取 refresh & access token 示例
|
||||
```python
|
||||
# Code example from https://github.com/secureworks/family-of-client-ids-research
|
||||
import msal
|
||||
@@ -106,7 +106,7 @@ from typing import Any, Dict, List
|
||||
|
||||
# LOGIN VIA CODE FLOW AUTHENTICATION
|
||||
azure_cli_client = msal.PublicClientApplication(
|
||||
"04b07795-8ddb-461a-bbee-02f9e1bf7b46" # ID for Azure CLI client
|
||||
"00b41c95-dab0-4487-9791-b9d2c32c80f2" # ID for Office 365 Management
|
||||
)
|
||||
device_flow = azure_cli_client.initiate_device_flow(
|
||||
scopes=["https://graph.microsoft.com/.default"]
|
||||
@@ -144,31 +144,32 @@ scopes=["https://graph.microsoft.com/.default"],
|
||||
)
|
||||
pprint(new_azure_cli_bearer_tokens_for_graph_api)
|
||||
```
|
||||
### 其他访问令牌字段
|
||||
### Other access token fields
|
||||
|
||||
- **appid**: 用于生成令牌的应用程序 ID
|
||||
- **appidacr**: 应用程序身份验证上下文类引用指示客户端的身份验证方式,对于公共客户端,值为 0,如果使用了客户端密钥,则值为 1
|
||||
- **acr**: 身份验证上下文类引用声明在最终用户身份验证未满足 ISO/IEC 29115 的要求时为 "0"。
|
||||
- **amr**: 身份验证方法指示令牌是如何被验证的。值为“pwd”表示使用了密码。
|
||||
- **groups**: 指示主体是哪些组的成员。
|
||||
- **iss**: 发行者标识生成令牌的安全令牌服务 (STS)。例如 https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/(uuid 是租户 ID)
|
||||
- **oid**: 主体的对象 ID
|
||||
- **tid**: 租户 ID
|
||||
- **iat, nbf, exp**: 签发时间(何时签发)、不早于(在此时间之前不能使用,通常与 iat 相同)、过期时间。
|
||||
- **appid**: 用来生成 token 的 Application ID
|
||||
- **appidacr**: Application Authentication Context Class Reference,指示客户端如何被认证;对于 public client 值为 0,若使用 client secret 则值为 1
|
||||
- **acr**: Authentication Context Class Reference 声明,当终端用户的认证未满足 ISO/IEC 29115 要求时为 "0"。
|
||||
- **amr**: Authentication method,指示 token 的认证方式。值为 “pwd” 表示使用了密码。
|
||||
- **groups**: 指示主体所属的组。
|
||||
- **iss**: 指示生成该 token 的 security token service (STS)。例如 https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/(该 uuid 为 tenant ID)
|
||||
- **oid**: 主体的 object ID
|
||||
- **tid**: Tenant ID
|
||||
- **iat, nbf, exp**: Issued at(签发时间),Not before(不可在此时间之前使用,通常与 iat 相同),Expiration time(过期时间)。
|
||||
|
||||
## FOCI 令牌特权提升
|
||||
|
||||
之前提到过,刷新令牌应与生成时的 **scopes**、**应用程序**和 **租户** 绑定。如果打破了这些边界,可能会提升特权,因为将能够生成访问其他资源和租户的访问令牌,用户可以访问这些资源,并且具有比最初预期更多的范围。
|
||||
## FOCI Tokens Privilege Escalation
|
||||
|
||||
此外,**所有刷新令牌都可以这样做** 在 [Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/)(Microsoft Entra 账户、Microsoft 个人账户以及 Facebook 和 Google 等社交账户)中,因为正如 [**文档**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) 所提到的:“刷新令牌绑定于用户和客户端的组合,但 **不绑定于资源或租户**。客户端可以使用刷新令牌获取 **在其有权限的任何资源和租户组合** 中的访问令牌。刷新令牌是加密的,只有 Microsoft identity platform 可以读取它们。”
|
||||
前文提到 refresh tokens 应该与其生成时的 **scopes**、生成时的 **application** 和 **tenant** 绑定。如果这些边界中的任何一个被破坏,就可能发生权限提升 —— 可以生成对用户有访问权限的其他资源和 tenant 的 access tokens,且可能比最初预期拥有更多的 scopes。
|
||||
|
||||
此外,请注意 FOCI 应用程序是公共应用程序,因此 **不需要密钥** 来进行服务器身份验证。
|
||||
此外,在 [Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/)(Microsoft Entra accounts、Microsoft personal accounts,以及像 Facebook 和 Google 这样的 social accounts)中,**所有 refresh tokens 都可能发生这种情况**,因为如 [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) 所述:“Refresh tokens are bound to a combination of user and client, but **aren't tied to a resource or tenant**. A client can use a refresh token to acquire access tokens **across any combination of resource and tenant** where it has permission to do so. Refresh tokens are encrypted and only the Microsoft identity platform can read them.”
|
||||
|
||||
然后在 [**原始研究**](https://github.com/secureworks/family-of-client-ids-research/tree/main) 中报告的已知 FOCI 客户端可以 [**在这里找到**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv)。
|
||||
另外,注意 FOCI applications 是 public applications,所以**不需要 secret**即可向服务器进行认证。
|
||||
|
||||
### 获取不同的范围
|
||||
在 [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) 中报告的已知 FOCI clients 可在 [**found here**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv) 找到。
|
||||
|
||||
继续之前的示例代码,在此代码中请求了一个不同范围的新令牌:
|
||||
### Get different scope
|
||||
|
||||
延续前面的示例代码,下面这段代码请求了一个用于不同 scope 的新 token:
|
||||
```python
|
||||
# Code from https://github.com/secureworks/family-of-client-ids-research
|
||||
azure_cli_bearer_tokens_for_outlook_api = (
|
||||
@@ -185,7 +186,7 @@ scopes=[
|
||||
)
|
||||
pprint(azure_cli_bearer_tokens_for_outlook_api)
|
||||
```
|
||||
### 获取不同的客户端和范围
|
||||
### 获取不同的 client 和 scopes
|
||||
```python
|
||||
# Code from https://github.com/secureworks/family-of-client-ids-research
|
||||
microsoft_office_client = msal.PublicClientApplication("d3590ed6-52b3-4102-aeff-aad2292ab01c")
|
||||
@@ -201,27 +202,28 @@ scopes=["https://graph.microsoft.com/.default"],
|
||||
# How is this possible?
|
||||
pprint(microsoft_office_bearer_tokens_for_graph_api)
|
||||
```
|
||||
## 找到令牌的地方
|
||||
## 在哪里可以找到 tokens
|
||||
|
||||
从攻击者的角度来看,了解在受害者的PC被攻破时,在哪里可以找到访问令牌和刷新令牌是非常有趣的:
|
||||
从攻击者的角度,当受害者的 PC 被攻破时,了解在哪里能够找到 access 和 refresh tokens 非常有价值:
|
||||
|
||||
- 在 **`<HOME>/.Azure`**
|
||||
- 位于 **`<HOME>/.Azure`**
|
||||
- **`azureProfile.json`** 包含过去登录用户的信息
|
||||
- **`clouds.config` 包含** 订阅的信息
|
||||
- **`service_principal_entries.json`** 包含应用程序凭据(租户ID、客户端和密钥)。仅在Linux和macOS上
|
||||
- **`msal_token_cache.json`** 包含访问令牌和刷新令牌。仅在Linux和macOS上
|
||||
- **`service_principal_entries.bin`** 和 **`msal_token_cache.bin`** 在Windows中使用,并使用DPAPI加密
|
||||
- **`msal_http_cache.bin`** 是HTTP请求的缓存
|
||||
- 加载它: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)`
|
||||
- **`AzureRmContext.json`** 包含使用Az PowerShell的先前登录信息(但没有凭据)
|
||||
- 在 **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** 中有几个 `.bin` 文件,包含使用用户DPAPI加密的 **访问令牌**、ID令牌和帐户信息。
|
||||
- 可以在 **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`** 中的 `.tbres` 文件中找到更多 **访问令牌**,这些文件包含使用DPAPI加密的访问令牌的base64。
|
||||
- 在Linux和macOS中,可以通过运行 `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` 从Az PowerShell(如果使用)获取 **访问令牌、刷新令牌和ID令牌**。
|
||||
- 在Windows中,这只会生成ID令牌。
|
||||
- 可以通过检查 `$HOME/.local/share/.IdentityService/` 是否存在来查看是否在Linux和macOS中使用了Az PowerShell(尽管包含的文件是空的且无用)。
|
||||
- 如果用户在浏览器中 **登录了Azure**,根据这篇 [**文章**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web),可以通过 **重定向到localhost** 开始身份验证流程,使浏览器自动授权登录,并接收刷新令牌。请注意,只有少数几个FOCI应用程序允许重定向到localhost(如az cli或PowerShell模块),因此必须允许这些应用程序。
|
||||
- **`clouds.config contains`** 包含有关订阅的信息
|
||||
- **`service_principal_entries.json`** 包含应用凭证 (tenant id, clients and secret)。仅在 Linux & macOS
|
||||
- **`msal_token_cache.json`** 包含 access tokens 和 refresh tokens。仅在 Linux & macOS
|
||||
- **`service_principal_entries.bin`** 和 msal_token_cache.bin 在 Windows 上使用并受 DPAPI 加密
|
||||
- **`msal_http_cache.bin`** 是 HTTP 请求的缓存
|
||||
- 加载方式: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)`
|
||||
- **`AzureRmContext.json`** 包含使用 Az PowerShell 的历史登录信息(但不含凭证)
|
||||
- 在 **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** 下有多个 `.bin` 文件,包含 **access tokens**、ID tokens 和账户信息,均用用户的 DPAPI 加密。
|
||||
- 还可以在 **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`** 中的 `.tbres` 文件里找到更多 **access tokens**;这些文件包含用 DPAPI 加密并 base64 编码的 access tokens。
|
||||
- 在 Linux 与 macOS 上,如果使用了 Az PowerShell,可运行 `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` 来获取 **access tokens, refresh tokens and id tokens**
|
||||
- 在 Windows 上这只会生成 id tokens。
|
||||
- 可以通过检查 `$HOME/.local/share/.IdentityService/` 是否存在来判断在 Linux 和 macOS 上是否使用过 Az PowerShell(尽管其中的文件为空且没用)
|
||||
- 如果用户使用浏览器登录了 Azure,根据这篇 [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web),可以以重定向到 localhost 的方式启动认证流程,使浏览器自动授权登录,并接收 refresh token。注意,只有少数 FOCI 应用允许重定向到 localhost(例如 az cli 或 powershell 模块),因此这些应用必须被允许。
|
||||
- 博客中解释的另一种方法是使用工具 [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow),它可以使用任何应用,因为它会 **获取 OAuth code,然后从最终认证页面标题中取得 refresh token**,使用 redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient`。
|
||||
|
||||
## 参考文献
|
||||
## References
|
||||
|
||||
- [https://github.com/secureworks/family-of-client-ids-research](https://github.com/secureworks/family-of-client-ids-research)
|
||||
- [https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md](https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md)
|
||||
|
||||
Reference in New Issue
Block a user