我正在研究应用程序级别的 Business Central API 权限如何在 AzureAD/EntraID 中工作。
我希望我的应用程序无需登录用户即可访问 Business Central 中的高级敏感数据。
为此,我要求管理员授予对我在 EntraID 中注册的应用程序的访问权限:
然后我在 .NET 中创建了一个控制台应用程序,并尝试代表 Azure 中注册的应用程序调用 Business Central。我假设列出 Business Central 中的所有环境。
static async Task Main(string[] args)
{
const string clientID = "<Client ID from Azure AD>";
const string authority = "https://login.microsoftonline.com/<Tenant ID>/v2.0";
const string clientSecret = "Secret Value";
string[] scopes = new string[] { "https://api.businesscentral.dynamics.com/.default" };
var clientApp = ConfidentialClientApplicationBuilder.Create(clientID)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri(authority))
.Build();
try
{
var result = await clientApp.AcquireTokenForClient(scopes).ExecuteAsync();
string accessToken = result.AccessToken;
Console.WriteLine(accessToken);
await RequestToBusinessCentral(accessToken);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
static async Task RequestToBusinessCentral(string accessToken)
{
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
string apiEndpoint = "https://api.businesscentral.dynamics.com/v2.0/admin/environments";
string apiEndpoint = "https://api.businesscentral.dynamics.com/v2.0/</sandbox/api/v1.0/companies
var response = await httpClient.GetAsync(apiEndpoint);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
Console.WriteLine("Response: ");
Console.WriteLine(data);
}
else
{
Console.WriteLine($"Error in HTTP Status: {response.StatusCode});
}
}
但是,我收到 400 Bad Request 或 401 Unahthorized 错误。
解码 JWT 令牌:
{
"aud": "https://api.businesscentral.dynamics.com",
"iss": "https://sts.windows.net/<Tenant ID>/",
"iat": 1710865738,
"nbf": 1710865738,
"exp": 1710869638,
"appid": "Client ID",
"appidacr": "1",
"idp": "https://sts.windows.net/<Tenant ID>/",
"idtyp": "app",
"oid": "Object ID",
"roles": [
"Automation.ReadWrite.All",
"app_access",
"AdminCenter.ReadWrite.All",
"API.ReadWrite.All"
],
"tid": "<Tenant ID>",
"ver": "1.0"
}
访问令牌看起来不错。
我按照Microsoft文档进行设置。
我尝试了不同的API端点,但结果是相同的。请求错误或未经授权。
在 Business Central 中,我在 Microsoft Entra 应用程序卡中注册了该应用程序。并为此应用程序分配超级(数据)权限。
我正在寻找一些可能导致此类问题的线索,我认为它可能位于不正确的 API 端点中? AzureAD/EntraID 中的配置不正确?或者 Business Central 中的配置不正确?
超级(数据)权限集允许读取所有表,仅此而已。但 BC API 端点从技术上讲是页面,因此这些请求至少需要执行相应页面的权限。此外,API 页面经常调用来自其他应用程序对象的代码,这些代码也必须得到权限集的允许。 400 或 401 响应很可能是由于 Business Central 中缺少权限,而不是令牌问题。 要开始故障排除,您还可以将
D365 API
权限集分配给您的应用程序:
这基本上是超级用户权限的类似物,不应该在生产中使用,但它是排除可能的 OAuth 令牌问题并开始缩小所需权限集范围的一个很好的起点。
分配这些权限集有一个技巧。它是不可分配的,不能直接从应用程序权限页面选择。如果您想在应用程序中设置它,请创建自定义权限集并选择
D365 APIV2
作为包含权限集。这将为您的应用程序提供超级用户访问权限。
此外,检查响应正文 - 它通常包含有关导致错误的特定 AL 对象的非常详细的信息,这可能有助于故障排除。