Как заставить Angular Client сообщать Identity Server, какой метод входа в систему использовать?

Я использую IdentityServer 4 с клиентом Angular 10, который использует OIDC Client JS:

Чтобы перенаправить пользователя для входа в систему, я вызываю signinRedirect на клиенте Angular:

UserManager.signinRedirect(args)

Это перенаправляет на IdentityServer 4 Acccount для входа в систему / a> действие:

[HttpGet]
public async Task<IActionResult> Login(string returnUrl) {
  var vm = await BuildLoginViewModelAsync(returnUrl);
  if (vm.IsExternalLoginOnly) {
    // we only have one option for logging in and it's an external provider
    return RedirectToAction("Challenge", "External", new { scheme = vm.ExternalLoginScheme, returnUrl });
  }
  return View(vm);
}

Вопрос

У меня есть внешние поставщики Google и Facebook, настроенные на сервере идентификации.

Как использовать signinRedirect и сообщить IdentityServer о необходимости использования внешнего поставщика, например Google, для входа в систему?

Я хотел бы обойти страницу входа в IdentityServer, где есть 3 варианта:

  1. Войти с именем пользователя и паролем
  2. Войти через Google
  3. Войти с Facebook

Таким образом, клиент Angular сообщит серверу Identity Server, какой метод входа в систему следует использовать.

Обновить

После некоторого исследования кажется, что в спецификации есть способ указать, какого провайдера использовать:

UserManager.signinRedirect({ acr_values: 'IdP:Google' }));

Затем на AccountController's BuildLogincView > есть следующее:

var context = await _interactionService.GetAuthorizationContextAsync(returnUrl);

if (request?.IdP != null && await _schemeProvider.GetSchemeAsync(request.IdP) != null) {

  var local = request.IdP == IdentityServer4.IdentityServerConstants.LocalIdentityProvider;

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

Я отлаживал context и получил следующее:

введите описание изображения здесь

AcrValues ​​анализируется, но IdP свойства не определен.

Разве AcrValues ​​не может решить эту проблему? Что мне не хватает?


person Miguel Moura    schedule 17.09.2020    source источник


Ответы (1)


Можно отправить сообщение поставщику удостоверений с помощью oidc-client, используя параметр args метода signinRedirect.

Если вы посмотрите на rel="nofollow> js / src / SigninRequest.js из их репозитория github, вы можете видеть, что вы можете предоставить следующие необязательные параметры для вышеупомянутого метода:

  • data,
  • prompt,
  • display,
  • max_age,
  • ui_locales,
  • id_token_hint,
  • login_hint,
  • acr_values,
  • resource,
  • response_mode,
  • request,
  • request_uri,
  • extraQueryParams,
  • request_type,
  • client_secret,
  • extraTokenParams,
  • skipUserInfo

Позже в коде, в строке 75 этой версии файла, у них есть следующее:

for(let key in extraQueryParams){
  url = UrlUtility.addQueryParam(url, key, extraQueryParams[key])
}

Это означает, что они позволяют разработчикам использовать extraQueryParams для предоставления пользовательских параметров.

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

UserManager.signinRedirect({ 
  extraQueryParams: {
    useExternalProvider: "google"
  }});

Чтобы получить доступ к этому параметру на вашем IdentityServer, найдите строку, которая вызывает GetAuthorizationContextAsync, и проверьте параметры сообщения протокола следующим образом:

var context = await interaction.GetAuthorizationContextAsync(returnUrl);
var externalProviderToUse = context.Parameters.Get("useExternalProvider");

Обычно это BuildLoginViewModelAsync(string returnUrl) метод, если вы использовали их QuickStart.

Оттуда вы можете получить внешние параметры входа в систему из базы данных или из того места, где вы храните эти параметры, и вместо перенаправления пользователей на страницу входа перенаправьте их прямо на ваш ExternalLogin(string provider, string returnUrl) с помощью RedirectToAction.

ИЗМЕНИТЬ

Если вы хотите использовать параметр acr_values для этого и более поздних версий в контексте авторизации IdentityServer, если хотите использовать свойство Idp, вы можете вызвать:

// "idp:" is case sensitive
UserManager.signinRedirect({ acr_values: 'idp:Google' }));
person Dejan Janjušević    schedule 17.09.2020
comment
Большое спасибо за подробное объяснение. Тем временем я провел еще несколько исследований и обнаружил, что в этом случае, возможно, следует использовать AcrValues ​​вместо extraQueryParams. Однако мне не удалось заставить его работать, поскольку IdP не определен в контексте. Что вы думаете? Я только что добавил обновление к своему вопросу. - person Miguel Moura; 17.09.2020
comment
@MiguelMoura префикс должен быть idp: - чувствительным к регистру. Я обновил ответ - person Dejan Janjušević; 17.09.2020