首页 > 解决方案 > IdentityServer 4 - 多选项卡登录 400 错误

问题描述

我有一个 .net core 3.1 MVC IdentityServer4 应用程序(由 Idsrv 人员提供的量身定制的快速入门应用程序),我使用它对使用 oidc-client 库构建的 SPA 进行身份验证,并且我最近能够复制一个问题关于尝试登录 Identity Server 时不时出现的 400 错误。

  1. 在 Chrome/Firefox/Edge 上打开两个单独的选项卡并导航到两个选项卡上的客户端应用程序的路径(例如 https://localhost:5001)。由于用户尚未登录 (https://localhost:5002),这两个选项卡都正确重定向到我的身份服务器实例的 URL。

  2. 使用用户名和密码,甚至是外部 OIDC 客户端登录第一个选项卡 - 这工作正常。

  3. 尝试使用用户名和密码登录第二个选项卡

  4. 发生 400 错误,在检查日志后,我得到以下 CORS 问题(我认为这并不相关):

    [15:51:29 调试] IdentityServer4.Hosting.CorsPolicyProvider CORS 请求路径:/Account/Login from origin: null 但被忽略,因为路径不适用于允许的 IdentityServer CORS 端点

  5. 如果我在浏览器中单击返回,登录页面会再次显示,然后我可以按预期登录。

总而言之,一旦用户成功登录到第一个选项卡,当用户第一次尝试登录到 IdentityServer 时,第二个选项卡总是会抛出 400 错误。我真的很难弄清楚为什么会这样 - 而且 CORS 错误消息也有点奇怪,因为当我点击返回并尝试第二次登录时它工作正常。

new Client
            {
                ClientId = "WebApp",
                ClientName = "Web App",

                AllowedGrantTypes = GrantTypes.Code,
                RequireClientSecret = false,
                RequirePkce = true,

                AccessTokenType = AccessTokenType.Reference, // This ensures tokens are revoked on logout

                RedirectUris = {
                    $"{webClientHost}/Oidc/SigninOidc",
                    $"{webClientHost}/Oidc/SilentRefresh"
                },
                PostLogoutRedirectUris = { webClientHost + "/" },

                AllowedCorsOrigins = { webClientOrigin },

                AllowedScopes = new List<string>
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    IdentityServerSettings.ApiScopeName
                },

                AllowAccessTokensViaBrowser = true,
                AccessTokenLifetime = (int) TimeSpan.FromMinutes(Convert.ToDouble(isAppSettings.WebAccessTokenLifetime)).TotalSeconds,
                RequireConsent = false
            }

有没有人经历过这样的事情?这可能与我的设置有关,还是 Identity Server 4 Quickstart 应用程序的已知缺陷?我一直在尝试调试,但是我遇到的 400 错误意味着调试甚至没有成功,所以我很挣扎。谢谢

标签: c#identityserver4oidc-client-js

解决方案


该问题与身份服务器无关/由 ASP.Net Core 如何使用防伪令牌引起。在许多情况下,此问题与 github https://github.com/IdentityServer/IdentityServer4/issues/2676上报告的问题相似。

在此特定实例中,一旦用户成功登录应用程序,身份服务器就会发出会话 cookie,因此请求令牌和防伪令牌不同步。

由于预加载的登录页面依赖于旧的防伪令牌,一旦请求开始处理,系统就会抛出以下异常 -

“防伪令牌验证失败。”防伪 cookie 令牌和请求令牌不匹配。

这是堆栈帧 -

Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException:防伪 cookie 令牌和请求令牌不匹配。在 Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.ValidateRequestAsync(HttpContext httpContext) 在 Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ValidateAntiforgeryTokenAuthorizationFilter.OnAuthorizationAsync( AuthorizationFilterContext 上下文)

由于防伪令牌验证在操作之前执行,因此授权失败并且请求处理被中止,执行控制永远不会到达登录代码。


推荐阅读