Microsoft Graph – 从应用注册中查找服务主体

huangapple go评论51阅读模式
英文:

Microsoft Graph - Find service principal from app registration

问题

我正在使用客户端凭据流登录到应用程序注册:

var certificateBytes = Convert.FromBase64String(certificate);
X509Certificate2 adCertificate = new X509Certificate2(certificateBytes, certificatePassword);
IConfidentialClientApplication confidentialClientApp = ConfidentialClientApplicationBuilder.Create(_clientId)
    .WithAuthority(AzureCloudInstance.AzurePublic, _tenantId)
    .WithCertificate(adCertificate)
    .Build();
var storageProperties = new StorageCreationPropertiesBuilder("TokenCache.plaintext", tokenCacheDirectory)
    .WithUnprotectedFile()
    .Build();
var cacheHelper = MsalCacheHelper.CreateAsync(storageProperties).Result;
cacheHelper.RegisterCache(_confidentialClientApp.UserTokenCache);

var silentToken = await _confidentialClientApp.AcquireTokenForClient(new string[] { "https://graph.microsoft.com/.default" }).ExecuteAsync();
var graphServiceClient = new Microsoft.Graph.GraphServiceClient(new Microsoft.Graph.DelegateAuthenticationProvider(async (requestMessage) =>
{
    var authResult = await _confidentialClientApp.AcquireTokenForClient(new string[] { "https://graph.microsoft.com/.default" }).ExecuteAsync();
    requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
})
);

然后,使用证书登录到应用程序注册后,我需要查找应用程序的对象标识和刚刚登录的服务主体的标识,类似于:

var applicationId = await graphServiceClient.GetMyAppRegistrationId();
var servicePrincipalId = await graphServiceClient.GetServicePrincipalIdOfAppRegistration();
英文:

I am logging onto an app registration using client credential flow:

var certificateBytes = Convert.FromBase64String(certificate);
X509Certificate2 adCertificate = new X509Certificate2(certificateBytes, certificatePassword);
IConfidentialClientApplication confidentialClientApp = ConfidentialClientApplicationBuilder.Create(_clientId)
    .WithAuthority(AzureCloudInstance.AzurePublic, _tenantId)
    .WithCertificate(adCertificate)
    .Build();
var storageProperties = new StorageCreationPropertiesBuilder("TokenCache.plaintext", tokenCacheDirectory)
    .WithUnprotectedFile()
    .Build();
var cacheHelper = MsalCacheHelper.CreateAsync(storageProperties).Result;
cacheHelper.RegisterCache(_confidentialClientApp.UserTokenCache);

var silentToken = await _confidentialClientApp.AcquireTokenForClient(new string[] { "https://graph.microsoft.com/.default" }).ExecuteAsync();
var graphServiceClient = new Microsoft.Graph.GraphServiceClient(new Microsoft.Graph.DelegateAuthenticationProvider(async (requestMessage) =>
{
    var authResult = await _confidentialClientApp.AcquireTokenForClient(new string[] { "https://graph.microsoft.com/.default" }).ExecuteAsync();
    requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
})
);

Then, having logged onto the app registration using the certificate I need to find out object id of the application and the id of the service principal I have just logged on as. Something like:

var applicationId = await graphServiceClient.GetMyAppRegistrationId();
var servicePrincipalId = await graphServiceClient.GetServicePrincipalIdOfAppRegistration();

答案1

得分: 1

GraphServiceClient 没有直接获取应用程序 ID 或服务主体 ID 的方法。

如果你有一个令牌,可以使用一些令牌解码器从元数据中获取 oidappId

oid 声明应该代表服务主体 ID

appId 声明代表应用程序 ID。

C#示例

NuGet包 System.IdentityModel.Tokens.Jwt 中有类 JwtSecurityTokenHandler,可用于解码访问令牌。

var token = "eyJ0eXAiOiJK...";
var handler = new JwtSecurityTokenHandler();
var jwtSecurityToken = handler.ReadJwtToken(token);

var oidClaim = jwtSecurityToken.Claims.FirstOrDefault(x => x.Type == "oid");
string servicePrincipalId = null;
if (oidClaim != null)
{
    servicePrincipalId = oidClaim.Value;
}
else
{
    servicePrincipalId = jwtSecurityToken.Payload["oid"] as string;
}

var appIdClaim = jwtSecurityToken.Claims.FirstOrDefault(x => x.Type == "appid");
string appId = null;
if (appIdClaim != null)
{
    appId = appIdClaim.Value;
}
else
{
    appId = jwtSecurityToken.Payload["appid"] as string;
}

如果要获取应用程序资源,可以使用筛选器

GET https://graph.microsoft.com/v1.0/applications?$filter=appId eq '{app_id}' 

C#示例

await graphServiceClient.Applications
    .Request()
    .Filter("appId eq '{app_id}'")
    .GetAsync();

上述代码需要 Application.Read.All 权限。

英文:

GraphServiceClient has no method to get application id or service principal id directly.

If you have a token you can use some token decoder to get oid and appId from metadata.

iod claim should represent service principal id

appId claim represents application id

Example for C#

NuGet package System.IdentityModel.Tokens.Jwt has the class JwtSecurityTokenHandler which can be used for decoding access token.

var token = "eyJ0eXAiOiJK...";
var handler = new JwtSecurityTokenHandler();
var jwtSecurityToken = handler.ReadJwtToken(token);

var oidClaim = jwtSecurityToken.Claims.FirstOrDefault(x => x.Type == "oid");
string servicePrincipalId = null;
if (oidClaim != null)
{
    servicePrincipalId = oidClaim.Value;
}
else
{
    servicePrincipalId = jwtSecurityToken.Payload["oid"] as string;
}

var appIdClaim = jwtSecurityToken.Claims.FirstOrDefault(x => x.Type == "appid");
string appId = null;
if (appIdClaim != null)
{
    appId = appIdClaim.Value;
}
else
{
    appId = jwtSecurityToken.Payload["appid"] as string;
}

If you want to get application resource then you can use filter

GET https://graph.microsoft.com/v1.0/applications?$filter=appId eq '{app_id}' 

C#

await graphServiceClient.Applications
    .Request()
    .Filter("appId eq '{app_id}'")
    .GetAsync();

The code above requires permission Application.Read.All.

huangapple
  • 本文由 发表于 2023年4月6日 21:07:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75949892.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定