Как реализовать проверку подлинности Windows с помощью IdentityServer 4
Как правильно реализовать проверку подлинности Windows с помощью сервера идентификации 4?
Есть ли образцы для этого?
Я посмотрел исходный код IdentityServer 4 и в проекте Host в AccountController. Я заметил, что есть проверки подлинности Windows, и они реализованы как внешний поставщик. Но я не могу работать с конфигурацией.
Кто-нибудь успешно реализовал проверку подлинности Windows с помощью idsrv4 и как?
Ответы
Ответ 1
Скоро будет больше документации:
https://identityserver4.readthedocs.io
Но короче - да с точки зрения IdentityServer Аутентификация Windows является внешним провайдером (в отличие от основного файла cookie аутентификации IS).
Нет ничего, что вам нужно сделать для реализации проверки подлинности Windows - просто используйте хост, который его поддерживает.
Это либо
- Kestrel с интеграцией IIS
- Weblistener
В обоих случаях вы вызываете машину Windows, бросая вызов схеме Negotiate
или NTLM
. Это не специфично для IS, а как работает ASP.NET Core.
Наш пользовательский интерфейс быстрого запуска показывает, как это сделать - проверьте AccountController.
https://github.com/IdentityServer/IdentityServer4.Quickstart.UI
Ответ 2
Для тех, кто сталкивается с этим в результатах поиска, у которых возникает проблема с запуском быстрого запуска с быстрым стартом ASPNET Identity, вот недостающие части.
По большей части вы хотите использовать код ASPNET Identity, используя SignInManager для тяжелого подъема. Как только вы доберетесь туда и добавите код auth в окне быстрого запуска, вы должны дойти до точки, где все выглядит так, как будто оно работает, но вы получаете нуль в этой строке в обратном вызове:
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
Чтобы Windows рассматривалась как реальный внешний провайдер, вместо добавления "схемы" к свойствам auth вокруг строки 163, вы хотите изменить ключ на "LoginProvider":
properties.Items.Add("LoginProvider", AccountOptions.WindowsAuthenticationSchemeName);
Я использую запрос домена для получения дополнительной информации о моих пользователях, выглядит примерно так:
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
using (UserPrincipal up = UserPrincipal.FindByIdentity(pc, wp.Identity.Name))
{
if (up == null)
{
throw new NullReferenceException($"Unable to find user: {wp.Identity.Name}");
}
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, up.Sid.Value));
id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.Identity.Name));
id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name));
id.AddClaim(new Claim(JwtClaimTypes.Email, up.EmailAddress));
id.AddClaim(new Claim(Constants.ClaimTypes.Upn, up.UserPrincipalName));
id.AddClaim(new Claim(JwtClaimTypes.GivenName, up.GivenName));
id.AddClaim(new Claim(JwtClaimTypes.FamilyName, up.Surname));
}
Какие претензии вы добавляете, зависит от вас, но вам нужен один из типов ClaimTypes.NameIdentifier для поиска SigninManager. SID кажется лучшим для меня. Последнее, что нужно изменить, - вызов SignInAsync для использования правильной схемы по строке 178-181:
await HttpContext.SignInAsync(IdentityConstants.ExternalScheme, new ClaimsPrincipal(id), properties);
Если вы не переопределяете схемы по умолчанию, которые IdentityServer4 использует в .net core 2, это правильная схема по умолчанию. И теперь ваш вызов GetExternalLoginInfoAsync в обратном вызове будет работать, и вы можете продолжить!
Ответ 3
В AccountOptions.cs
вашего Identity Server убедитесь, что public static bool WindowsAuthenticationEnabled = true;
, я думаю, что у quickstart это по умолчанию было false
Убедитесь, что ваш пул приложений для сервера идентификации использует учетную запись с надлежащими учетными данными (я предполагаю учетную запись, которая может запрашивать AD). Я не мог использовать встроенные учетные записи AppPoolIdentity, LocalService или Network. LocalSystem почти сработала, но через другую ошибку.
Войдите как минимум один раз на этот веб-сервер с учетной записью, созданной выше для пула приложений. Эта учетная запись не должна быть каким-либо администратором. Задайте дополнительные параметры в пуле приложений, чтобы загрузить профиль.
Используйте анонимные и учетные данные Windows, установленные в IIS в корневом каталоге вашего удостоверения, вам не нужны дайджест или базовые.
Ответ 4
Выпуск:
Как и я, вы, вероятно, попали сюда после того, как вы выполнили все краткие руководства и учебные пособия по ASP.NET IdentityServer 4, которые вы можете найти в надежде на то, что ваша аутентификация Windows будет работать, но не получится, за исключением:
Exception: External authentication error
Host.Quickstart.Account.ExternalController.Callback() in ExternalController.cs, line 89
Тогда вы, возможно, обнаружили этот result?.Succeeded
имеет значение false после вызова HttpContext.AuthenticateAsync(...)
в функции Callback
а остальные свойства результатов имеют значение null
...
Объяснение:
Причина этого заключается в том, что схема аутентификации, проверяемая во время обратного вызова, является IdentityConstants.ExternalScheme
...
Однако во время функции ProcessWindowsLoginAsync
вызов HttpContext.SignInAsync
настроен на использование схемы проверки подлинности IdentityServerConstants.ExternalCookieAuthenticationScheme
, которая не соответствует ProcessWindowsLoginAsync
вызову и, в свою очередь, приводит к неудачной попытке проверки подлинности Windows.
Решение:
Поэтому все, что нам нужно сделать, чтобы решить эту проблему, это изменить вызов HttpContext.SignInAsync
чтобы он соответствовал схеме, ожидаемой обратным вызовом:
await HttpContext.SignInAsync(IdentityConstants.ExternalScheme, new ClaimsPrincipal(id), props);
После этого ваш вход в систему с использованием аутентификации Windows будет успешным, и ваш " танец победы " может начаться !!!
Большое спасибо Дэну за его ответ!
Без его решения я, вероятно, все равно буду рвать на себе волосы.
Дэн также упоминает, что вы должны изменить Properties.Items["scheme"]
на "LoginProvider"
...
Однако это не является необходимым и приведет к FindUserFromExternalProviderAsync
функции FindUserFromExternalProviderAsync
, так как она ожидает, что поставщик входа будет указан в свойстве "scheme"
.
Источник быстрого запуска IdentityServer, по-видимому, был обновлен с тех пор, как Дэн опубликовал свой ответ, поэтому я подумал, что лучше всего опубликовать обновление для тех из вас, кто столкнулся с той же проблемой.