Аутентификация клиента SPA с помощью веб-API Core 3.1 с использованием Microsoft Identity - PullRequest
0 голосов
/ 08 мая 2020

Я думаю, что мой главный вопрос заключается в том, какой поток аутентификации мне следует использовать - от имени или неявного гранта? Однако моя аутентификация и авторизация, настроенные в Startup.cs, могут быть неправильными, и я ошибаюсь, поэтому извиняюсь, если это так.

У меня есть Angular SPA в Azure и Net Framework API также работает в Azure.

Веб-API был перенесен на Net Core 3.1.

В нашем каталоге Azure у меня есть два зарегистрированных приложения. Один для API, а другой для SPA. Я добавил идентификатор клиента SPA для авторизованных клиентов в WEB API.

Стоит отметить, что службы приложений на самом деле работают в другом каталоге (я думаю, это нормально, но просто упомяну)

Вот соответствующая настройка аутентификации / авторизации в Azure AD.

    private void ConfigureAzureAD(IServiceCollection services, IMvcBuilder mvcBuilder)
        {
            services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
                .AddAzureAD(options => Configuration.Bind("AzureAd", options));

            services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
            {
                options.Authority = options.Authority + "/v2.0/";
                options.TokenValidationParameters.ValidateIssuer = true;
            });

            mvcBuilder.AddMvcOptions(options =>
            {
                var policy = new AuthorizationPolicyBuilder().
                    RequireAuthenticatedUser().
                    Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            }).
            SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }
 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseResponseCaching();
            }

            app.UseStaticFiles();
            app.UseCors(CORS_POLICY);


            if (UseAzureAD)
            {
                app.UseHttpsRedirection();
            }

            app.UseRouting();
            app.UseCookiePolicy();
            app.UseAuthorization();
            app.UseAuthentication();

            app.UseMvc();
        }

Я могу успешно использовать API напрямую, и он аутентифицируется.

SPA использует Angular ADAL . Что, если я правильно прочитал, не будет работать для конечных точек Microsoft Identity V2. - нам все еще нужно перейти на MSAL, хотя у меня все еще возникают проблемы с пониманием конечного процесса аутентификации (который, я думаю, является моим основным вопросом). текущая конфигурация ADAL, но когда он попадает в API и перенаправляется на https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/authorize? с идентификатором и токеном.

Он зависает при перенаправлении, и это ошибка CORS, потому что источник равен нулю. Я знаю, что это ожидается, поскольку SPA настроен неправильно.

API действительно вызывает MS Graph API для получения групп для пользователя (но использует идентификатор клиента и секрет клиента, чтобы получить токен доступа для вызова MS Graph), поэтому я не думаю, что это означает, что мне нужно использовать On-Behalf-Of-Flow (я видел этот пост Проверка подлинности в Microsoft Graph с помощью SPA, а затем использование токена в веб-API )?

Я рассмотрел этот пример https://github.com/Azure-Samples/ms-identity-javascript-angular-spa-aspnetcore-webapi для неявного потока грантов.

В этом примере я заметил схему аутентификации JwtBearerDefualts, что имеет смысл, поскольку ID-токены являются JWT, поэтому я сомневаюсь в моей стартовой конфигурации API.

Вот этот бит, который вызывает MS Graph в API, который, вероятно, необходим для лучшего ответа, какой из двух потоков мне следует использовать (снова он получает токен доступа с секретным кодом клиента).

private async Task<IReadOnlyCollection<string>> LoadReportGroupsCurrentUserCanRead()
        {
            var objectID = claimsPrincipal
                .Claims
                .FirstOrDefault(c => c.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier")
                ?.Value;

            var graphServiceClient = await GetGraphServiceClient();

            var groups = await graphServiceClient
                .Groups
                .Request()
                .GetAsync();

            var memberGroups = await graphServiceClient
                .Users[objectID]
                .GetMemberGroups(true)
                .Request()
                .PostAsync();

            return memberGroups.Select(mg => groups.SingleOrDefault(g => g.Id == mg))
                .Where(g => g?.DisplayName?.EndsWith(" Report Group", StringComparison.InvariantCultureIgnoreCase) == true)
                .Select(g => g.Description)
                .Where(name => !string.IsNullOrWhiteSpace(name))
                .ToArray();
        }

        private async Task<GraphServiceClient> GetGraphServiceClient()
        {

            string authority = new Uri(microsoftLogin, tenantID).AbsoluteUri;
            var authenticationContext = new AuthenticationContext(authority);
            var clientCredential = new ClientCredential(clientID, clientSecret);

            var authenticationResult = await authenticationContext.AcquireTokenAsync("https://graph.microsoft.com", clientCredential);

            var authProvider = new DelegateAuthenticationProvider(requestMessage =>
            {
                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authenticationResult.AccessToken);
                return Task.CompletedTask;
            });
            return new GraphServiceClient(authProvider);
        }

Наконец, я думаю, что наш SPA использует версия Angular, не поддерживающая Angular MSAL. Могу я просто использовать Vanilla MSAL JS (не думаю, что сейчас у нас есть время обновить Angular)?

1 Ответ

0 голосов
/ 09 мая 2020

Вы должны использовать неявный поток и msal- angular. Он поддерживает Angular от 4 до 9. Также я бы не рекомендовал использовать ванильные библиотеки в Angular, если нет другого выбора.

ADAL устарел и не поддерживает модель конвергентного приложения (рабочая + личная учетные записи), поэтому вам нужно перейти на MSAL.

Следуйте Создайте веб-API с ASP. NET Core и Перенести с ASP. NET Core 2.2 до 3.0 , чтобы удалить такой код:

mvcBuilder.AddMvcOptions(options =>
            {
                var policy = new AuthorizationPolicyBuilder().
                    RequireAuthenticatedUser().
                    Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            })

И вместо этого создайте свой контроллер из Controller и украсьте их атрибутом ApiController .

А также это, поскольку это. NET 3.1:

.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

Ваша аутентификация MS Graph аутентифицируется с помощью учетных данных клиента , что является обычным подходом для текущей архитектуры приложения. Если вы не добавляете слишком много привилегированных разрешений , тогда все будет в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...