Пусть angular-oauth2-oidc извлекает токен доступа из других вкладок - PullRequest
0 голосов
/ 16 мая 2018

Я использую библиотеку angular-oauth2-oidc в сочетании с неявным потоком (с сервером IdentityServer4). Я успешно настроил предложение тихого обновления из документов .

Вот как я запускаю вещи в сервисе-оболочке:

private userSubject = new Subject<User>();

constructor(private config: ConfigService, private oAuthService: OAuthService)
{ }

// Called on app load:
configure(): void {
    const config: AuthConfig = {
      issuer: this.config.getIdentityUrl(),
      logoutUrl: this.config.getIdentityUrl() + '/connect/endsession',
      redirectUri: window.location.origin + '/',
      silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html',
      clientId: 'my_client_id',
      scope: 'openid profile my_api',
      sessionChecksEnabled: true,
    };

    this.oAuthService.configure(config);
    this.oAuthService.tokenValidationHandler = new JwksValidationHandler();

    this.oAuthService
      .loadDiscoveryDocumentAndLogin()
      .then((_) => this.loadUserProfile());

    this.oAuthService.setupAutomaticSilentRefresh();
}

private loadUserProfile() {
  this.oAuthService.loadUserProfile()
    .then((userProfile) => {
      const user = new User(userProfile['name']);
      this.userSubject.next(user);
    });
}

Однако, если я открою приложение в новой вкладке, пользователь также будет перенаправлен на IdentityServer (и сразу же вернется в мое приложение).

Мой вопрос: можно ли заставить библиотеку извлекать существующий токен доступа (и, необязательно, информацию о пользователе) с других вкладок того же происхождения, чтобы предотвратить перенаправления? (Предпочитается, так как для этого не требуется Ajax вызовы.)

В качестве альтернативы, есть ли простой способ попробовать использовать механизм Silent Refresh, прежде чем мы отправим кого-то на IdentityServer?

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Сначала: у меня почему-то возникла мысль, что sessionStorage подходит для токенов и что следует избегать localStorage. Но это был другой проект, в котором были задействованы более мощные (обновляемые) токены, и с неявным потоком у меня были только кратковременные токены доступа, поэтому localStorage не намного (если вообще) небезопаснее, чем sessionStorage.

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

Оказывается, в библиотеку встроена поддержка использования localStorage в качестве резервного хранилища для токенов и других данных. Сначала я пытался:

// This doesn't work properly though, read on...
this.oAuthService.setStorage(localStorage);

Но этот способ начальной загрузки не работал для моего случая, см. выпуск 321 в списке проблем библиотек GitHub для моего входа в систему. Повторяя решение (или обходной путь?) Из этого потока, я решил некоторые проблемы, выполнив это в модуле приложения providers:

{ provide: OAuthStorage, useValue: localStorage },

Теперь библиотека будет правильно использовать localStorage, и новые вкладки (и даже новые окна) автоматически ее подберут.


В качестве сноски, если вы не хотите использовать localStorage, например, из соображений безопасности, вы также можете предоставить собственное хранилище, если оно реализует интерфейс OAuthStorage. Ваша собственная реализация может затем использовать любой из доступных методов взаимодействия между вкладками, чтобы «запрашивать» данные из других вкладок, возвращаясь к sessionStorage, если это необходимо.

0 голосов
/ 16 мая 2018

Существует объяснение, почему он всегда обращается к IdentityServer для уточнения текущего пользователя, и это код, который вы показали.

Каждый раз, когда вы открываете вкладку, ваше приложение запускается, икод выше выполнен.Теперь все эти библиотеки oidc, которые поддерживают SPA'a и поток Implicit, хранят пользовательские данные (access_token ...) в хранилище сеансов браузера.Открыв новую вкладку, вы получаете новый сеанс.

Моя точка зрения здесь - вам нужно что-то сделать, прежде чем пытаться пройти аутентификацию на Identity Server.Я указываю на что-то вроде перемещения всей пользовательской информации с Session storage на Local storage.Тогда вкладки, которые находятся под одним и тем же приложением (соответственно того же источника), будут иметь общий Local storage.

Таким образом, ваш поток при запуске приложения должен выглядеть примерно так:

  1. Проверьте локальное хранилище для информации о пользователе
  2. Если существует, настройте службу аутентификации (включая автоматическое обновление), но не пытайтесь войти в систему.И переместить данные в хранилище сеансов (не уверен, что это необходимо, но я предполагаю, что библиотека их там будет искать)
  3. Если нет - войдите в систему, а затем переместите данные из хранилища сеансов в локальноеone
  4. И, конечно, при обратном обратном вызове в режиме без вывода сообщений вам придется обновлять значения в локальном хранилище (они должны обновляться библиотекой в ​​сеансе).
  5. И, наконец,но не в последнюю очередь - при выходе из системы вам придется очистить.

Для меня это кажется решением для вас.Теперь - вам решать, стоит ли это накладных расходов.

PS: Просто, чтобы уточнить - я не пробовал.Я не могу гарантировать, что это будет работать, но следуя порядку событий, оно должно.

...