使用 WindowsAuthentication 时出现 IdentityServer4 错误
IdentityServer4 error when using WindowsAuthentication
我成功遵循了 IdentityServer4 上的 Deblokt 教程 (https://deblokt.com/2020/01/24/01-identityserver4-quickstart-net-core-3-1/)。本教程使用 IdentityServer4 QuickstartUI。 Userid/password 使用 AspNet Identity 数据库的身份验证正在运行。
我使用的是最新的 .Net Core (3.1),它与教程略有不同,但它正在运行。
现在我正在尝试添加 Windows 身份验证并遇到运行时错误。令我困惑的是,在 用户通过 windows 成功验证后 发生了错误。我在 Visual Studio 2019 内的 Windows 10 机器上本地 运行 处于调试模式,使用 Google Chrome.
根据 IdentityServer4 文档 (https://identityserver4.readthedocs.io/en/latest/topics/windows.html#using-kestrel),我将其添加到我的 Startup.cs:
services.Configure<IISServerOptions>(iis =>
{
iis.AuthenticationDisplayName = "Windows";
iis.AutomaticAuthentication = false;
});
然后我右键单击该项目,选择 "Properties",选择 "Debug" 选项卡,然后选中 "Windows Authentication":
这使得 "Windows" 按钮在我导航到 /Account/Login 时可见:
单击 "Windows" 按钮时,在 ExternalController "Challenge" 方法中处理回发,"Windows" 作为提供者参数,“~/”作为 returnUrl 参数。由于提供程序参数是 "Windows",此方法调用 ProcessWindowsLoginAsync,传递 returnUrl 参数。
第一次,ProcessWindowsLoginAsync 调用 HttpContext.AuthenticateAsync("Windows"),其中 returns 一个 null Principal,这导致方法重新调用 /External/Challenge("Windows"),第二次调用 ProcessWindowsLoginAsync,后者又调用 HttpContext.AuthenticateAsync("Windows"),第二次调用成功--HttpContext.AuthenticateAsync returns 一个 windows 委托人(就是我),我可以在调试器中查看它并看到它包含我的所有详细信息。
ProcessWindowsLoginAsync 然后进行此调用:
await HttpContext.SignInAsync(
IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme,
new ClaimsPrincipal(id),
props
);
这执行没有错误。 "id" 参数是一个 ClaimsIdentity,其中包含从我的 windows 身份、主题和名称中提取的 2 个声明。
此时一切似乎都很好。 ProcessWindowsLoginAsync 方法以重定向到 /External/Callback 结束。这是发生错误的地方。方法 /External/Callback 方法在顶部包含这段代码,并抛出您看到的异常。由于未知原因 HttpContext.AuthenticateAsync 没有成功。
var result = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme);
if (result?.Succeeded != true)
{
throw new Exception("External authentication error");
}
"result"对象的"Succeeded"值为false,"None"值为true,其他属性(Principal、Properties、Ticket)均为null。
如有任何建议,我们将不胜感激。
修复方法是在 ExternalController.cs 第 173 行更改此设置:
await HttpContext.SignInAsync(
IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme,
new ClaimsPrincipal(id),
props);
为此:
await HttpContext.SignInAsync(
IdentityConstants.ExternalScheme,
new ClaimsPrincipal(id),
props);
事后看来这似乎很明显:AuthenticateAsync 和 SignInAsync 应该引用相同的方案。
在摸索解决方案后,我注意到 IdentityServer4 github 从 2018 年 3 月开始就有一个已关闭的错误报告,但我不知道为什么这个错误仍然是快速入门的一部分:https://github.com/IdentityServer/IdentityServer4/issues/2166
我遇到了类似的问题,IdentityServer 代码为 Google 登录
抛出了“外部身份验证错误”
[HttpGet]
public async Task<IActionResult> Callback()
{
// read external identity from the temporary cookie
var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
if (result?.Succeeded != true)
{
throw new Exception("External authentication error");
}
我必须在 Startup.cs:
中添加外部 SignInScheme (IdentityServerConstants.ExternalCookieAuthenticationScheme)
services.AddAuthentication()
.AddGoogle(options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "my_client_id";
options.ClientSecret = "my_client_secret";
});
我成功遵循了 IdentityServer4 上的 Deblokt 教程 (https://deblokt.com/2020/01/24/01-identityserver4-quickstart-net-core-3-1/)。本教程使用 IdentityServer4 QuickstartUI。 Userid/password 使用 AspNet Identity 数据库的身份验证正在运行。
我使用的是最新的 .Net Core (3.1),它与教程略有不同,但它正在运行。
现在我正在尝试添加 Windows 身份验证并遇到运行时错误。令我困惑的是,在 用户通过 windows 成功验证后 发生了错误。我在 Visual Studio 2019 内的 Windows 10 机器上本地 运行 处于调试模式,使用 Google Chrome.
根据 IdentityServer4 文档 (https://identityserver4.readthedocs.io/en/latest/topics/windows.html#using-kestrel),我将其添加到我的 Startup.cs:
services.Configure<IISServerOptions>(iis =>
{
iis.AuthenticationDisplayName = "Windows";
iis.AutomaticAuthentication = false;
});
然后我右键单击该项目,选择 "Properties",选择 "Debug" 选项卡,然后选中 "Windows Authentication":
这使得 "Windows" 按钮在我导航到 /Account/Login 时可见:
单击 "Windows" 按钮时,在 ExternalController "Challenge" 方法中处理回发,"Windows" 作为提供者参数,“~/”作为 returnUrl 参数。由于提供程序参数是 "Windows",此方法调用 ProcessWindowsLoginAsync,传递 returnUrl 参数。
第一次,ProcessWindowsLoginAsync 调用 HttpContext.AuthenticateAsync("Windows"),其中 returns 一个 null Principal,这导致方法重新调用 /External/Challenge("Windows"),第二次调用 ProcessWindowsLoginAsync,后者又调用 HttpContext.AuthenticateAsync("Windows"),第二次调用成功--HttpContext.AuthenticateAsync returns 一个 windows 委托人(就是我),我可以在调试器中查看它并看到它包含我的所有详细信息。
ProcessWindowsLoginAsync 然后进行此调用:
await HttpContext.SignInAsync(
IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme,
new ClaimsPrincipal(id),
props
);
这执行没有错误。 "id" 参数是一个 ClaimsIdentity,其中包含从我的 windows 身份、主题和名称中提取的 2 个声明。
此时一切似乎都很好。 ProcessWindowsLoginAsync 方法以重定向到 /External/Callback 结束。这是发生错误的地方。方法 /External/Callback 方法在顶部包含这段代码,并抛出您看到的异常。由于未知原因 HttpContext.AuthenticateAsync 没有成功。
var result = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme);
if (result?.Succeeded != true)
{
throw new Exception("External authentication error");
}
"result"对象的"Succeeded"值为false,"None"值为true,其他属性(Principal、Properties、Ticket)均为null。
如有任何建议,我们将不胜感激。
修复方法是在 ExternalController.cs 第 173 行更改此设置:
await HttpContext.SignInAsync(
IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme,
new ClaimsPrincipal(id),
props);
为此:
await HttpContext.SignInAsync(
IdentityConstants.ExternalScheme,
new ClaimsPrincipal(id),
props);
事后看来这似乎很明显:AuthenticateAsync 和 SignInAsync 应该引用相同的方案。
在摸索解决方案后,我注意到 IdentityServer4 github 从 2018 年 3 月开始就有一个已关闭的错误报告,但我不知道为什么这个错误仍然是快速入门的一部分:https://github.com/IdentityServer/IdentityServer4/issues/2166
我遇到了类似的问题,IdentityServer 代码为 Google 登录
抛出了“外部身份验证错误” [HttpGet]
public async Task<IActionResult> Callback()
{
// read external identity from the temporary cookie
var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
if (result?.Succeeded != true)
{
throw new Exception("External authentication error");
}
我必须在 Startup.cs:
中添加外部 SignInScheme (IdentityServerConstants.ExternalCookieAuthenticationScheme) services.AddAuthentication()
.AddGoogle(options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "my_client_id";
options.ClientSecret = "my_client_secret";
});