在 Azure 中使用带有客户端密码的 GraphServiceClient 的授权异常
Authorisation Exception using GraphServiceClient with Client Secret in Azure
我正在开发一种工具(Windows 表单)来自动执行某些流程。我需要阅读特定 AD 组的成员并在每个成员日历中创建一个事件。
为此,我在 C# 应用程序中使用了 GraphServiceClient。
- 我在 Azure 门户中添加了“应用程序注册”:Jansen Automation
- 我已经添加了所有需要的权限并获得了管理员同意
- 我创建了一个 ClientSecret,并将其值复制到我的代码中
接下来我想使用 https://docs.microsoft.com/en-us/graph/sdks/choose-authentication-providers?tabs=CS#tabpanel_2_CS 中的示例代码从 AD 中读取所有组:
private GraphServiceClient GetClient()
{
try
{
var scopes = new[] { "https://graph.microsoft.com/.default" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = _options.TenantId;
// Values from app registration
var clientId = _options.ClientId;
var clientSecret = _options.ClientSecret;
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
return graphClient;
}
catch (Exception ex)
{
_logger.LogError(ex, ex.Message);
throw;
}
}
public async Task<List<string>> GetAllGroups()
{
try
{
var client = GetClient();
var groups = await client.Groups
.Request()
.Header("ConsistencyLevel", "eventual")
.GetAsync();
return groups?.Select(g => g.DisplayName).ToList();
}
catch (Exception ex)
{
throw;
}
}
结果异常:
我在这里错过了什么?
我弄明白了,我授予了委派权限而不是应用程序权限。我已将其更改为应用程序,我的代码现在如下所示:
var scopes = new string[] { "https://graph.microsoft.com/.default" };
var tenantId = clientConfig.TenantId;
// Configure the MSAL client as a confidential client
var confidentialClient = ConfidentialClientApplicationBuilder
.Create(clientConfig.ClientId)
.WithAuthority($"https://login.microsoftonline.com/{tenantId}/v2.0")
.WithClientSecret(clientConfig.Secret)
.Build();
// Build the Microsoft Graph client. As the authentication provider, set an async lambda
// which uses the MSAL client to obtain an app-only access token to Microsoft Graph,
// and inserts this access token in the Authorization header of each API request.
return new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) => {
// Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
var authResult = await confidentialClient
.AcquireTokenForClient(scopes)
.ExecuteAsync();
// Add the access token in the Authorization header of the API request.
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
})
);
});
我正在开发一种工具(Windows 表单)来自动执行某些流程。我需要阅读特定 AD 组的成员并在每个成员日历中创建一个事件。 为此,我在 C# 应用程序中使用了 GraphServiceClient。
- 我在 Azure 门户中添加了“应用程序注册”:Jansen Automation
- 我已经添加了所有需要的权限并获得了管理员同意
- 我创建了一个 ClientSecret,并将其值复制到我的代码中
接下来我想使用 https://docs.microsoft.com/en-us/graph/sdks/choose-authentication-providers?tabs=CS#tabpanel_2_CS 中的示例代码从 AD 中读取所有组:
private GraphServiceClient GetClient()
{
try
{
var scopes = new[] { "https://graph.microsoft.com/.default" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = _options.TenantId;
// Values from app registration
var clientId = _options.ClientId;
var clientSecret = _options.ClientSecret;
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
return graphClient;
}
catch (Exception ex)
{
_logger.LogError(ex, ex.Message);
throw;
}
}
public async Task<List<string>> GetAllGroups()
{
try
{
var client = GetClient();
var groups = await client.Groups
.Request()
.Header("ConsistencyLevel", "eventual")
.GetAsync();
return groups?.Select(g => g.DisplayName).ToList();
}
catch (Exception ex)
{
throw;
}
}
结果异常:
我在这里错过了什么?
我弄明白了,我授予了委派权限而不是应用程序权限。我已将其更改为应用程序,我的代码现在如下所示:
var scopes = new string[] { "https://graph.microsoft.com/.default" };
var tenantId = clientConfig.TenantId;
// Configure the MSAL client as a confidential client
var confidentialClient = ConfidentialClientApplicationBuilder
.Create(clientConfig.ClientId)
.WithAuthority($"https://login.microsoftonline.com/{tenantId}/v2.0")
.WithClientSecret(clientConfig.Secret)
.Build();
// Build the Microsoft Graph client. As the authentication provider, set an async lambda
// which uses the MSAL client to obtain an app-only access token to Microsoft Graph,
// and inserts this access token in the Authorization header of each API request.
return new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) => {
// Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
var authResult = await confidentialClient
.AcquireTokenForClient(scopes)
.ExecuteAsync();
// Add the access token in the Authorization header of the API request.
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
})
);
});