c# - 如何在.net核心应用程序中基于组进行授权?
问题描述
网络核心应用程序。我的要求是添加基于组的授权。我是 Azure AD 的用户。我属于一些以 BR 和 AR 开头的组名。只有属于 AR 组的用户才能访问我的 API。目前我的客户端应用程序是 Swagger,我只通过 swagger 访问 APIS。
例如,在启动时我可以有下面的代码。
services.AddAuthorization(options => {
options.AddPolicy("AR-BitBucket-User",
policyBuilder => policyBuilder.RequireClaim("groups",
"6be4f534-dcf5-489e-b57d-c7bb46be8d6b"));
});
在控制器中,
[Authorize("AR-BitBucket-User")]
在上述方法中,我是硬编码,但我不想硬编码。首先,我没有在 JWT 令牌中获取组信息,我得到了
hasGroups:true 在我的 JWT 令牌中。我想从 Graph API 中获取它,而不是硬编码。有人可以帮我怎么做吗?我无法在互联网上获得任何相关示例。那么有人可以帮助我吗?
解决方案
如果您想配置您的应用程序以接收组声明,您需要像 在 Manifest 文件中一样设置“ groupMembershipClaims ”值。SecurityGroup
在 Application Registration Portal 上的应用程序设置页面中,单击“Manifest”以打开内联清单编辑器。
通过找到“groupMembershipClaims”设置并将其值设置为“SecurityGroup”来编辑清单。
保存清单。
{
...
"errorUrl": null,
"groupMembershipClaims": "SecurityGroup",
...
}
当为应用程序启用组声明时,Azure AD 会在 JWT 和 SAML 令牌中包含一个声明,其中包含用户所属的所有组的对象标识符 (objectId),包括传递组成员身份。
但请注意,为确保令牌大小不超过 HTTP 标头大小限制,Azure AD 限制了它包含在组声明中的 objectId 数量。如果用户是超过超额限制(SAML 令牌为 150,JWT 令牌为 200)的组的成员,则 Azure AD 不会在令牌中发出组声明。相反,它在令牌中包含一个超额声明,指示应用程序查询 Graph API 以检索用户的组成员资格。更多详情,请参阅博客。
所以你需要做一些过程:
检查声明_claim_names,其中一个值为组。这表明超龄。
如果找到,请调用 _claim_sources 中指定的端点以获取用户组。
如果没有找到,请查看用户组的组声明。
当然,您可以直接调用Microsoft Graph API来退出当前用户的组,而无需使用group claims
关于如何基于该组进行授权,您可以创建一个策略。更多详细信息,请参阅文档。例如
启动.cs
services.AddAuthorization(options =>
{
options.AddPolicy("CheckGroups", policy =>
policy.Requirements.Add(new GroupsCheckRequirement("YourGroupID")));
});
services.AddScoped<IAuthorizationHandler, GroupsCheckHandler>();
GroupsCheckRequirement.cs:
public class GroupsCheckRequirement : IAuthorizationRequirement
{
public string groups;
public GroupsCheckRequirement(string groups)
{
this.groups = groups;
}
}
GroupsCheckHandler.cs :
public class GroupsCheckHandler : AuthorizationHandler<GroupsCheckRequirement>
{
private readonly ITokenAcquisition tokenAcquisition;
private readonly IMSGraphService graphService;
public GroupsCheckHandler(ITokenAcquisition tokenAcquisition, IMSGraphService MSGraphService)
{
this.tokenAcquisition = tokenAcquisition;
this.graphService = MSGraphService;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
GroupsCheckRequirement requirement)
{
string accessToken = await tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(new[] { Constants.ScopeUserRead, Constants.ScopeDirectoryReadAll });
User me = await graphService.GetMeAsync(accessToken);
IList<Group> groups = await graphService.GetMyMemberOfGroupsAsync(accessToken);
var result = false;
foreach (var group in groups)
{
if (requirement.groups.Equals(group.Id))
{
result = true;
}
}
if (result)
{
context.Succeed(requirement);
}
}
}
然后使用策略:
[Authorize(Policy = "CheckGroups")]
此外,您还可以通过 ASP.NET Core 中间件库来实现它。asp.net 中间件通过RoleClaimType
在TokenValidationParameters
. 由于groups
声明包含安全组的对象 ID 而不是实际名称,因此您将使用组 ID 而不是组名。有关详细信息,请参阅示例。
启动.cs
// The following lines code instruct the asp.net core middleware to use the data in the "groups" claim in the Authorize attribute and User.IsInrole()
// See https://docs.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.2 for more info.
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
// Use the groups claim for populating roles
options.TokenValidationParameters.RoleClaimType = "groups";
});
然后使用它
[Authorize(Roles = “Group-object-id")] // In controllers
// or
User.IsInRole("Group-object-id"); // In methods
推荐阅读
- python - 使用列中每个唯一 ID 对 DataFrame 进行 JSON 打包
- html - 日期字段默认文本“DD-MM-YYYY”不在移动设备上显示,但在桌面上显示
- pytest - 为什么 pytest 运行这种不需要的行为?
- rust - 将 HashMap 值转换为 BinaryHeap
- python - Pyspark:有没有一种有效的方法来排除只有空值但 pk 的行?
- r - 立即重新单击按钮无效
- javascript - html显示属性不能使用javascript更改
- linux-kernel - 重新接通交流电源后以太网端口不工作
- asp.net - ASP.NET 将记录从 Excel 复制到 SQL Server - 性能缓慢
- python - 与 ovito 库结合使用时,Python 的 matplotlib 中 plt.figure() 中的“无法在没有 QApplication 的情况下创建 QWidget”