英文:
Get all appRoles on an Azure AD App Registration in ASP.NET
问题
在我的ASP.NET MVC Core项目中,我希望将在应用程序注册中设置的所有AppRoles作为列表显示在我的视图中。
目前,我尝试了以下操作:
var servicePrincipal = await _graphServiceClient.Applications[_configuration["AzureAd:AppRegistrationId"]]
.Request()
.Select("appRoles")
.GetAsync();
我已经授予了应用程序Application.Read.All
和Directory.Read.All
的API权限,但仍然出现错误:
ServiceException: Code: Authorization_RequestDenied
Message: Insufficient privileges to complete the operation
问题:
- 我是不是正在正确的路径上实现我的需求,只是缺少了正确的权限?
- 有人知道需要什么权限吗?
- 有没有其他方法来完成这个任务?
- 我尝试从声明中获取角色,但那只显示用户的角色,而不是应用程序注册中设置的所有角色。
提前感谢任何帮助!
英文:
In my ASP.NET MVC Core project, I want all the AppRoles that are set up in the App Registration as a list to display in my view.
Currently I have attempted the following:
var servicePrincipal = await _graphServiceClient.Applications[_configuration["AzureAd:AppRegistrationId"]]
.Request()
.Select("appRoles")
.GetAsync();
I have granted the application the API permissions Application.Read.All
and Directory.Read.All
, but I still get error:
> ServiceException: Code: Authorization_RequestDenied <br>
> Message: Insufficient privileges to complete the operation
Questions:
- Am I even on the right path to achieve what I want and just missing the correct permission?
- Does anyone know what permission is required then?
- Is there a different way to achieve this task?
- I have attempted getting the roles out of the claim, but that only displays the user's roles, not all the roles that are set up on the App Registration
Thank you in advance for any assistance!
答案1
得分: 1
根据此处
的文档,Application.Read.All
是正确的权限来读取有关应用程序的信息。
我相信您收到此错误的原因是因为您已将此权限分配给您的应用程序,但似乎正在发出 Graph API 请求的用户没有该权限。
请检查分配给发出请求的用户的权限,并确保他们具有执行此请求所需的适当权限。
英文:
Based on the documentation here
, Application.Read.All
is the right permission to read information about an application.
I believe the reason you are getting this error is because you have assigned this permission to your application but it seems the user who's making the Graph API request does not have that permission.
Please check the permissions assigned to the user who's making the request and make sure that they have the appropriate permissions to make this request.
答案2
得分: 1
虽然这不是对我最初问题的直接回答,但我最终通过采用不同的方法解决了这个问题。
我使用了 Microsoft.Graph.Auth 包来生成凭据,然后使用该凭据连接到 Graph(基本上作为我的应用程序注册)。以下是该函数:
public async Task<List<string>> GetGraphApiClient(IConfiguration configuration)
{
// 配置应用程序
var clientApplication = ConfidentialClientApplicationBuilder
.Create(configuration["AzureAd:ClientId"])
.WithTenantId(configuration["AzureAd:TenantId"])
.WithClientSecret(configuration["AzureAd:ClientSecret"])
.Build();
// 创建将管理身份验证令牌的 ClientCredentialProvider
var authenticationProvider = new ClientCredentialProvider(clientApplication);
var graphClient = new GraphServiceClient(authenticationProvider);
// 调用 Graph API
var application = await graphClient.Applications["在此处放置应用程序对象的 ID"].Request().GetAsync();
List<string> appRoles = new List<string>();
foreach (var app in application.AppRoles)
{
appRoles.Add(app.DisplayName);
}
return appRoles;
}
可能不是最佳方式,但能够正常工作,所以我很满意。
英文:
While this is not a direct answer to my original question, I ended resolving the issue by using a different approach.
I used the package Microsoft.Graph.Auth to generate a credential, then connect to Graph with that credential (basically connect as my Application Registration). Here's the function:
public async Task<List<string>> GetGraphApiClient(IConfiguration configuration)
{
// Configure application
var clientApplication = ConfidentialClientApplicationBuilder
.Create(configuration["AzureAd:ClientId"])
.WithTenantId(configuration["AzureAd:TenantId"])
.WithClientSecret(configuration["AzureAd:ClientSecret"])
.Build();
// Create ClientCredentialProvider that will manage auth token for you
var authenticationProvider = new ClientCredentialProvider(clientApplication);
var graphClient = new GraphServiceClient(authenticationProvider);
// Call Graph API
var application = await graphClient.Applications[<"Application object ID here">].Request().GetAsync();
List<string> appRoles = new List<string>();
foreach (var app in application.AppRoles)
{
appRoles.Add(app.DisplayName);
}
return appRoles;
}
Probably not the best way, but works, so I am happy.
答案3
得分: 1
Here's the translated content:
看起来我来晚了...
我使用了委派权限和应用程序权限,它们都没问题。
对于应用程序权限,可以使用以下代码轻松实现:
using Microsoft.Graph;
using Azure.Identity;
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "tenantId ";
var clientId = "clientId ";
var clientSecret = "clientSecret ";
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var res = await graphClient.Applications["azure_ad_app_object_id_instead_of_client_id"].Request().GetAsync();
var roles = res.AppRoles;
这需要应用程序类型的 API 权限:
如果我们想要使用委派 API 权限,因为这是一个 MVC 应用程序,我们需要首先将 AAD 认证集成到应用程序中。我们可以按照这个示例来做。一般来说,可以在 program.cs 中添加类似以下的代码:
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
builder.Services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "TenantId",
"TenantId": "TenantId",
"ClientId": "ClientId",
"ClientSecret": "ClientSecret",
"CallbackPath": "/home", //不要忘记在 Azure 门户中设置重定向 URL
"SignedOutCallbackPath ": "/signout-callback-oidc"
}
然后将 graphclient
注入到代码中并使用它来调用 Graph API:
private readonly GraphServiceClient _graphServiceClient;
public HomeController(GraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient;
}
public async Task<IActionResult> IndexAsync() {
var b = await _graphServiceClient.Applications["aad_app_object_id"].Request().GetAsync();
return View();
}
英文:
looks like I'm late...
I test with delegated permission and application permission, both of them are ok.
for application permission, it would be easy to do it with code like below:
using Microsoft.Graph;
using Azure.Identity;
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "tenantId ";
var clientId = "clientId ";
var clientSecret = "clientSecret ";
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var res = await graphClient.Applications["azure_ad_app_object_id_instead_of_client_id"].Request().GetAsync();
var roles = res.AppRoles;
This requires application type of api permission:
If we want to use the delegated api permission, since this is an MVC application, we need to integrate AAD authentication into the application first. We can follow this sample. To generally speaking, add codes in program.cs like this:
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
builder.Services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "TenantId",
"TenantId": "TenantId",
"ClientId": "ClientId",
"ClientSecret": "ClientSecret",
"CallbackPath": "/home", //don't forget to set redirect url in azure portal
"SignedOutCallbackPath ": "/signout-callback-oidc"
},
Then inject graphclient
into the code and use it call graph api,
private readonly GraphServiceClient _graphServiceClient;
public HomeController(GraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient;
}
public async Task<IActionResult> IndexAsync() {
var b = await _graphServiceClient.Applications["aad_app_object_id"].Request().GetAsync();
return View();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论