Используйте AD B2C и MSAL v2 с Angular, разрешая выборочные незащищенные вызовы веб-API.

Моя цель - позволить пользователям свободно просматривать сайт Angular 11+, читая данные, вызываемые из веб-API .NET, во время навигации. Только пользователи, которые хотят публиковать данные или получить доступ к определенным функциям, должны будут зарегистрироваться и войти в систему, используя службы идентификации AD B2C. Соответственно, контроллеры в службе внутреннего приложения помечаются [Авторизовать] или [AllowAnonymous] в зависимости от ситуации.

Сайт успешно поддерживает просмотр и публикацию для в систему пользователей, копируя подход из вошедшихпримера AzureAD .

      export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
  const protectedResourceMap = new Map<string, Array<string>>();
  protectedResourceMap.set(apiConfig.uri, apiConfig.scopes);
  return {
    interactionType: InteractionType.Redirect,
    protectedResourceMap
  };
}

Однако при использовании этого подхода httpInterceptor Msal, очевидно, срабатывает для каждого вызова базы данных, вызывая событие регистрации / входа в систему B2C на всех конечных точках, сводя на нет усилия по поддержке анонимного просмотра.

MSAL v1, по-видимому, поддерживает массив unprotectedResource, но в это не версии 2рекомендуется . Он также, по-видимому, поддерживает использование нулевых шаблонов, таких как

      const resourceMap: [string, string[]][] = [
  [`${apiBaseUrl}/health`, null],
  [`${apiBaseUrl}`, ['scope1', 'scope2']],
];

Поскольку этот объект v1 имеет другую форму, я пробовал это в v2, но безрезультатно

        const protectedResourceMap = new Map<string, Array<string>>();
  protectedResourceMap.set(apiConfig.uri + '/myreadabledata', []);
  protectedResourceMap.set(apiConfig.uri, apiConfig.scopes);

Я пробовал другие подходы, такие как установка protectedResourceMap исключительно для контроллеров, требующих авторизации. Это тоже не удалось.

        const protectedResourceMap = new Map<string, Array<string>>();
  protectedResourceMap.set(apiConfig.uri  + '/mycloseddata1' , apiConfig.scopes);
  protectedResourceMap.set(apiConfig.uri  + '/mycloseddata2' , apiConfig.scopes);

Как правильно этого добиться?

2 ответа

Я исправил это, обернув MsalInterceptor в собственный перехватчик. В настоящее время он применяет MsalInterceptor только после входа пользователя в систему, как показано ниже:

      import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';
import { MsalInterceptor, MsalService } from '@azure/msal-angular';

@Injectable()
export class RequestInterceptor implements HttpInterceptor {
  constructor(private authService: MsalService, private msalInterceptor: MsalInterceptor) {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    const accounts = this.authService.instance.getAllAccounts();
    const isLoggedIn = accounts.length > 0;

    if (isLoggedIn) {
      return this.msalInterceptor.intercept(request, next);
    } else {
      return next.handle(request);
    }
  }
}

Можно также выбрать другой тип фильтра (вместо того, чтобы просто смотреть, вошел ли пользователь в систему). Например, в пользовательском перехватчике может использоваться отдельная карта защищенных ресурсов. Таким образом, можно по-прежнему помечать ресурсы, которые защищены, и запускать автоматическое перенаправление входа в систему.

Я столкнулся с той же проблемой, что хотел, чтобы некоторые маршруты api были анонимными и не вызывали перенаправление для входа в систему. Удалось наткнуться на эту ссылку .

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

      const protectedResourceMap = new Map<string, Array<string>>();
protectedResourceMap.set(apiConfig.uri + '/myreadabledata/*', null);
protectedResourceMap.set(apiConfig.uri, apiConfig.scopes);

После чтения кода трюк, похоже, состоит в том, чтобы сначала поставить незащищенный путь (-ы) и вернуть ему область видимости null.

я бегу 2.0.0-beta.5 и это работает для меня при звонке GET uri/myreadabledata/{id}

Другие вопросы по тегам