身份服务器在 /connect/authorize/callback 中一直显示“显示登录:用户未通过身份验证”

Posted

技术标签:

【中文标题】身份服务器在 /connect/authorize/callback 中一直显示“显示登录:用户未通过身份验证”【英文标题】:Identity server is keep showing "Showing login: User is not authenticated" in /connect/authorize/callback 【发布时间】:2019-01-25 12:31:09 【问题描述】:

使用 IdentityServer4,我正在现有系统上实现代码流授权,该系统仅支持 IdentityServer 中的 ResourceOwnerPassword 授权类型并且运行良好。

我进入了一个用户被提升为认证,然后被重定向到server connect/authorize/callback的阶段

之后它不会进行身份验证并返回登录页面。从日志中,我得到以下信息:

    调用 IdentityServer 端点:IdentityServer4.Endpoints.AuthorizeCallbackEndpoint for /connect/authorize/callback

    ValidatedAuthorizeRequest

    
    "ClientId": "demo",
    "ClientName": "MVC Client Demo",
    "RedirectUri": "http://localhost:5002/signin-oidc",
    "AllowedRedirectUris": ["http://openidclientdemo.com:8001/signin-oidc",
    "http://localhost:5002/signin-oidc"],
    "SubjectId": "anonymous",
    "ResponseType": "code id_token",
    "ResponseMode": "form_post",
    "GrantType": "hybrid",
    "RequestedScopes": "openid profile default-api",
    "State": "CfDJ8DU4Xalc7d9HttaFlZ-UaDhGsjeeEccTfNiNZFz3yYZI9MfXjrXo2TAzT9f6-F2VEdC7bWtcD7HRJgkqrh4t0oTAe_47IBfcm5Fsde9bVRorq-CHcL6_c15Vz1G5LJyEzqX6tyjhcZ2g3J2JjxD1PME1W7sq9YSddhQUJmxt4bVi70wdTtXXp0tH0SKyb0vLCs3eIjOln792nobaFOCM7r3VJ8BfXfpDm2pOOmBlR7zCCBxFCivwj7Zmy5Tu8Z09MvzOaLEkPBSL5i9GyxmGiB0P6osBPYEDyoRfgy2qDigH3QqLmLYjfE6NrgcgIGO9kgXuUT52XgALV_ZKjNbih-Y",
    "Nonce": "636702233595840569.NGQ3NGVlODMtYTVhNy00MjM4LWFhNGQtNTFiZTE3ZjllZmUzNjU5MGNmNjktNjg3Yy00YmZlLWEwYWYtYmMzM2QxZmZlNjBk",
    "Raw": 
        "client_id": "demo",
        "redirect_uri": "http://localhost:5002/signin-oidc",
        "response_type": "code id_token",
        "scope": "openid profile default-api",
        "response_mode": "form_post",
        "nonce": "636702233595840569.NGQ3NGVlODMtYTVhNy00MjM4LWFhNGQtNTFiZTE3ZjllZmUzNjU5MGNmNjktNjg3Yy00YmZlLWEwYWYtYmMzM2QxZmZlNjBk",
        "state": "CfDJ8DU4Xalc7d9HttaFlZ-UaDhGsjeeEccTfNiNZFz3yYZI9MfXjrXo2TAzT9f6-F2VEdC7bWtcD7HRJgkqrh4t0oTAe_47IBfcm5Fsde9bVRorq-CHcL6_c15Vz1G5LJyEzqX6tyjhcZ2g3J2JjxD1PME1W7sq9YSddhQUJmxt4bVi70wdTtXXp0tH0SKyb0vLCs3eIjOln792nobaFOCM7r3VJ8BfXfpDm2pOOmBlR7zCCBxFCivwj7Zmy5Tu8Z09MvzOaLEkPBSL5i9GyxmGiB0P6osBPYEDyoRfgy2qDigH3QqLmLYjfE6NrgcgIGO9kgXuUT52XgALV_ZKjNbih-Y",
        "x-client-SKU": "ID_NET",
        "x-client-ver": "2.1.4.0",
        "accessToken": "4155a526-2bb1-4d88-ba3a-21cb3a91f266",
        "userId": "MQ=="
    
    

    显示登录:用户未通过身份验证


我不清楚是什么导致了身份验证失败,知道吗?

【问题讨论】:

从日志中发布异常 @Tseng 也不例外!或者至少没有显示在日志中 你确定吗? IdSrv4 应记录错误或异常,并提供更多信息,说明身份验证请求失败的原因 可能未映射所需的声明,并且通过路由用户最终到达登录页面。您希望用户访问的页面是否受到特定角色策略的保护? @Tseng 没错,很确定。虽然我将标志 IdentityModelEventSource.ShowPII 设置为 true 【参考方案1】:

TL;DR:使用 http + chrome 的默认身份服务器,不起作用。 Chrome 强制使用 SameSite=none 的 cookie 也具有 Secure 属性,因此您可能必须使用 HTTPS,或使用 @blow's answer 修改 cookie 策略。 Chromium blog

关于单点登录和 cookie 的一些上下文,

cookie 是服务器在response 上发送的一段信息,浏览器在随后的每个request 上发送回。

当您登录身份服务器时,它会发回多个 cookie,其中一个会识别您的会话。此 cookie 与属性 SameSite=none 一起发送,这允许您浏览的任何应用程序向您的身份服务器发出请求并将此 cookie 包含在其中。这样,对/connect/authorize 的调用就包含了这个cookie,并且identityserver 跳过了登录部分。 Voilà SSO

你在用Google Chrome吗?

Google Chrome 最近引入了一项更改,即所有带有 SameSite=none 属性的 cookie 必须包含 Secure 属性。

这两个属性的意思是:

SameSite:根据来源,控制浏览器在将 cookie 附加到对您网站的任何请求时的行为方式。

SameSite=strict: 不会在来自与来源不同的站点的请求中发送 cookie。这有助于防止CSRF 攻击。 SameSite=lax:类似于strict,但是当用户通过点击链接或发送表单故意启动请求时,cookie 会被发送。未根据脚本发起的请求发送。 SameSite=none:无论来自哪个来源,cookie 都会被包含在内。

Secure:表示 cookie 只能通过 HTTPS 发送。

IdentityServer 使用SameSite=none 发出这些cookie。这意味着当您在本地提供没有 HTTPS 的 IdentityServer 并使用 chrome 作为浏览器时,它不会让您登录,因为在您向服务器发布您的用户和密码后,响应将包括会话 cookie 但您的浏览器(chrome) 会拒绝它,因为它们没有标记为 secure,而是标记为 SameSite=none、and this combination is not allowed。

【讨论】:

如果你在本地开发中使用http重定向会导致这种情况。客户端 Web 和 ID 服务器都必须是 https。试试看。 是否可以更改 IdentityServer 中的 SameSite cookie 行为?我会设置 SameSite=Lax 或 Strict。 谢谢,我通过设置 CookiesPolicyOptions 成功地将 SameSite 设置为 Lax 我在这个问题上花了几个小时!阅读这篇文章的第一句话解决了我的问题!谢谢你!!!【参考方案2】:

Pablo Recalde answer解释了原因,正确的解决方案是使用HTTPS。

无论如何,你可以通过设置CookiesPolicyOptions来改变SameSite的值

将其设置为SameSiteMode.Lax,您至少可以强制使用SameSite=Lax

app.UseCookiePolicy(new CookiePolicyOptions  MinimumSameSitePolicy = SameSiteMode.Lax );

【讨论】:

以上是关于身份服务器在 /connect/authorize/callback 中一直显示“显示登录:用户未通过身份验证”的主要内容,如果未能解决你的问题,请参考以下文章

身份服务器端点 OIDC

检查用户是否已在IdentityServer 4中进行了身份验证

带有 docker-compose 的 Identity Server 4 在 /connect/authorize/callback 之后重定向到登录页面

如何解决 IdentityServer4 中的循环 - 连接/授权/回调?client_id=?

设置为允许使用提示=无静默续订

IdentityServer4 中的 CSRF 保护