如何为 GraphServiceClient 设置资源 URL 以获取组?
How to set resource URL for GraphServiceClient to fetch Groups?
我正在尝试使用从 JWT access token 中的 _claims_sources
收到的 groups:src1
端点值从图表 API 中获取广告组。
我的客户端正在使用客户端凭据,可以获取 AD 中所有用户和组的信息。
我是这样设置的:
private async Task<IList<Group>> GetUserGroupsAsync(string endpoint)
{
// Endpoint is from the claims in a previous OIDC request
// Setup a client if it does not exist
PrepareGraphApiClient();
// I can fetch my groups using the methods in the client
// var groupPage = await graphServiceClient.Me.MemberOf.Request().GetAsync();
// This is where I would like to use the resource URL received from the
// claims I receive in a previous OIDC request
var groupPageFromUrl = ???
...
}
private void PrepareGraphApiClient()
{
if (graphServiceClient != null) return;
try
{
AuthenticationContext authority = new AuthenticationContext(oidcOptions.Authority);
ClientCredential clientCredential = new ClientCredential(oidcOptions.ClientId, oidcOptions.ClientSecret);
var graphApiResource = "https://graph.microsoft.com";
AuthenticationResult authenticationResult = authority.AcquireTokenAsync(graphApiResource, clientCredential).Result;
graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider(
async requestMessage =>
{
// Add token to outgoing requests
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
}));
}
catch (Exception ex)
{
logger.LogDebug($"Could not create the graph client {ex}");
throw;
}
}
我可以使用 GraphServiceClient 声明中的资源 URL 还是必须设置 HttpClient 才能发出请求?
_claim_sources.src1
中标识的端点用于 Azure AD Graph,因此您使用的令牌需要用于 Azure AD Graph API (https://graph.windows.net
),而不是用于 Microsoft Graph (https://graph.microsoft.com
)。这也意味着您不能使用 Microsoft Graph SDK,因为 API 请求和响应根本不同。
您有两个选择:
(推荐)使用端点仅作为您必须进行查找的指示这一事实,并向 Microsoft 发出 等效 调用使用 Microsoft Graph SDK 的图形:
var memberOfIds = await graphServiceClient
.Users[userObjectId] # from the 'oid' in access token
.GetMemberObjects(securityEnabledOnly: true) # true if groupMembershipClaims is "SecurityGroup", false if it's "All"
.Request()
.PostAsync();
使用给定的终结点并使用(例如)HttpClient 构建您自己的 Microsoft Graph 请求。一个简单的例子:
using (var client = new HttpClient())
{
# Always get the token right before you use it. ADAL will take care of getting a new one
# if needed, or using an existing cached token if not.
authenticationResult =
authority.AcquireTokenAsync("https://graph.windows.net", clientCredential)
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
# Make the API request to Azure AD Graph. Note we have to include the api-version and
# the request body.
HttpResponseMessage response = await client.PostAsync(
$"{src}?api-version=1.6", new StringContent(
"{'securityEnabledOnly': true}", # true if groupMembershipClaims is "SecurityGroup", false if it's "All"
UnicodeEncoding.UTF8,
"application/json"));
if (response.IsSuccessStatusCode)
{
# Note we're deserializing as if it were a Microsoft Graph response to getMemberObjects,
# rather than an Azure AD Graph response. Though it works, this is somewhat risky, and
# it would be more correct to explicitly define the form of an Azure AD Graph response.
var memberOfIds = JsonConvert.DeserializeObject<DirectoryObjectGetMemberObjectsCollectionResponse>(
await response.Content.ReadAsStringAsync()).Value;
}
}
作为旁注,我注意到您有一个调用来获取您已提供给 Microsoft Graph 库的 DelegateAuthenticationProvider
之外的 令牌。您应该将 AcquireTokenAsync
调用 放在 中,以便它为每个 Microsoft Graph 请求检索一个新令牌。库 (ADAL) 将负责使用缓存令牌(如果可用)或发出新令牌请求(如果 none 可用或可用令牌已过期)。像这样:
graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider(
async requestMessage =>
{
// Get fresh token
AuthenticationResult authenticationResult =
await authority.AcquireTokenAsync(graphApiResource, clientCredential);
// Add token to outgoing requests
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
}));
我正在尝试使用从 JWT access token 中的 _claims_sources
收到的 groups:src1
端点值从图表 API 中获取广告组。
我的客户端正在使用客户端凭据,可以获取 AD 中所有用户和组的信息。
我是这样设置的:
private async Task<IList<Group>> GetUserGroupsAsync(string endpoint)
{
// Endpoint is from the claims in a previous OIDC request
// Setup a client if it does not exist
PrepareGraphApiClient();
// I can fetch my groups using the methods in the client
// var groupPage = await graphServiceClient.Me.MemberOf.Request().GetAsync();
// This is where I would like to use the resource URL received from the
// claims I receive in a previous OIDC request
var groupPageFromUrl = ???
...
}
private void PrepareGraphApiClient()
{
if (graphServiceClient != null) return;
try
{
AuthenticationContext authority = new AuthenticationContext(oidcOptions.Authority);
ClientCredential clientCredential = new ClientCredential(oidcOptions.ClientId, oidcOptions.ClientSecret);
var graphApiResource = "https://graph.microsoft.com";
AuthenticationResult authenticationResult = authority.AcquireTokenAsync(graphApiResource, clientCredential).Result;
graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider(
async requestMessage =>
{
// Add token to outgoing requests
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
}));
}
catch (Exception ex)
{
logger.LogDebug($"Could not create the graph client {ex}");
throw;
}
}
我可以使用 GraphServiceClient 声明中的资源 URL 还是必须设置 HttpClient 才能发出请求?
_claim_sources.src1
中标识的端点用于 Azure AD Graph,因此您使用的令牌需要用于 Azure AD Graph API (https://graph.windows.net
),而不是用于 Microsoft Graph (https://graph.microsoft.com
)。这也意味着您不能使用 Microsoft Graph SDK,因为 API 请求和响应根本不同。
您有两个选择:
(推荐)使用端点仅作为您必须进行查找的指示这一事实,并向 Microsoft 发出 等效 调用使用 Microsoft Graph SDK 的图形:
var memberOfIds = await graphServiceClient .Users[userObjectId] # from the 'oid' in access token .GetMemberObjects(securityEnabledOnly: true) # true if groupMembershipClaims is "SecurityGroup", false if it's "All" .Request() .PostAsync();
使用给定的终结点并使用(例如)HttpClient 构建您自己的 Microsoft Graph 请求。一个简单的例子:
using (var client = new HttpClient()) { # Always get the token right before you use it. ADAL will take care of getting a new one # if needed, or using an existing cached token if not. authenticationResult = authority.AcquireTokenAsync("https://graph.windows.net", clientCredential) client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken); # Make the API request to Azure AD Graph. Note we have to include the api-version and # the request body. HttpResponseMessage response = await client.PostAsync( $"{src}?api-version=1.6", new StringContent( "{'securityEnabledOnly': true}", # true if groupMembershipClaims is "SecurityGroup", false if it's "All" UnicodeEncoding.UTF8, "application/json")); if (response.IsSuccessStatusCode) { # Note we're deserializing as if it were a Microsoft Graph response to getMemberObjects, # rather than an Azure AD Graph response. Though it works, this is somewhat risky, and # it would be more correct to explicitly define the form of an Azure AD Graph response. var memberOfIds = JsonConvert.DeserializeObject<DirectoryObjectGetMemberObjectsCollectionResponse>( await response.Content.ReadAsStringAsync()).Value; } }
作为旁注,我注意到您有一个调用来获取您已提供给 Microsoft Graph 库的 DelegateAuthenticationProvider
之外的 令牌。您应该将 AcquireTokenAsync
调用 放在 中,以便它为每个 Microsoft Graph 请求检索一个新令牌。库 (ADAL) 将负责使用缓存令牌(如果可用)或发出新令牌请求(如果 none 可用或可用令牌已过期)。像这样:
graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider(
async requestMessage =>
{
// Get fresh token
AuthenticationResult authenticationResult =
await authority.AcquireTokenAsync(graphApiResource, clientCredential);
// Add token to outgoing requests
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
}));