Как сделать авторизацию на основе групп в основном приложении .net? - PullRequest
0 голосов
/ 24 октября 2019

чистое основное приложение. Мое требование - добавить групповую авторизацию. Я пользователь Azure AD. Я принадлежу к некоторым групповым именам, начинающимся с BR и AR. Пользователи, принадлежащие только к группам AR, должны иметь доступ к моим API. В настоящее время моим клиентским приложением является Swagger, и я использую APIS только через swagger.

Например, при запуске у меня может быть следующий код.

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. Может кто-нибудь помочь мне, как это сделать? Я не могу найти ни одного похожего примера в интернете. Так может кто-нибудь мне помочь?

1 Ответ

1 голос
/ 24 октября 2019

Если вы хотите настроить приложение для получения групповых заявок, вам нужно установить значение " groupMembershipClaims " как SecurityGroup в файле манифеста.

  1. На странице настроек приложения на портале регистрации приложений нажмите «Манифест», чтобы открыть встроенный редактор манифеста.

  2. Редактирование манифестапутем выбора параметра «groupMembershipClaims» и установки его значения в «SecurityGroup».

  3. Сохраните манифест.

    {
      ...
      "errorUrl": null,
      "groupMembershipClaims": "SecurityGroup",
      ...
    }

Когдагрупповое утверждение включено для приложения, Azure AD включает в токены JWT и SAML утверждение, содержащее идентификаторы объектов (objectId) всех групп, к которым принадлежит пользователь, включая транзитивное членство в группах.

Но учтите, что для того, чтобы размер токена не превышал ограничения размера заголовка HTTP, Azure AD ограничивает количество идентификаторов объектов, включаемых в утверждение групп. Если пользователь является участником большего числа групп, чем предел превышения (150 для токенов SAML, 200 для токенов JWT), то Azure AD не отправляет утверждение группы в токене. Вместо этого он включает избыточное требование в токене, которое указывает приложению на запрос API Graph для получения членства в группе пользователя. Для получения более подробной информации, пожалуйста, обратитесь к блогу .

enter image description here

Так что вам нужно выполнить какой-то процесс:

  1. Проверьте наличие в заявке _claim_names с одним из значений, являющихся группами. Это указывает на переизбыток.

  2. Если найден, вызовите конечную точку, указанную в _claim_sources, чтобы получить группы пользователей.

  3. Если ничего не найдено, посмотритев группы претензий для групп пользователей.

Конечно, вы можете напрямую позвонить Microsoft Graph API , чтобы удалить группы текущего пользователя без используя group claims

Что касается авторизации на основе этих групп, вы можете создать политику. Для получения более подробной информации, пожалуйста, обратитесь к документу . Например,

Startup.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 содержит идентификаторы объектов групп безопасности, а не фактические имена, вместо имен групп следует использовать идентификаторы групп. Для более подробной информации, пожалуйста, обратитесь к sample .

Startup.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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...