身份服务器在 /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 中一直显示“显示登录:用户未通过身份验证”的主要内容,如果未能解决你的问题,请参考以下文章
检查用户是否已在IdentityServer 4中进行了身份验证
带有 docker-compose 的 Identity Server 4 在 /connect/authorize/callback 之后重定向到登录页面