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

Hom*_*mam 21 c# openid oauth-2.0 asp.net-core identityserver4

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

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

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

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

  2. 验证授权请求

    {
    "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=="
    }
    
    Run Code Online (Sandbox Code Playgroud)

    }

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


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

Pab*_*lde 24

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

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

cookie 是服务器在 a 上发送的一条信息,response并且浏览器在随后的每个request.

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

你在用Google Chrome吗?

谷歌浏览器最近引入了一项更改,即所有随该属性发布的 cookie 都SameSite=none 必须包含该Secure属性。

这两个属性的意思是:

  • SameSite:控制浏览器在将 cookie 附加到向您的站点发出的任何请求时的行为方式,基于来源。

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

IdentityServer 使用SameSite=none. 这意味着当您在本地使用没有 HTTPS 的 IdentityServer 并使用 chrome 作为浏览器时,它不会让您登录,因为在您将用户和密码 POST 到服务器后,响应将包含会话 cookie 但您的浏览器(chrome) 会拒绝它,因为它们没有被标记为secure但是,被标记为SameSite=none并且这种组合是不允许的

  • 谢谢,我通过设置 [CookiesPolicyOptions](/sf/answers/4252411551/) 成功将 SameSite 设置为 Lax (2认同)
  • 我在这个问题上花了几个小时!阅读这篇文章的第一句话解决了我的问题!感谢您!!! (2认同)

blo*_*low 16

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

无论如何,您可以SameSite通过设置更改值CookiesPolicyOptions

设置为SameSiteMode.LaxSameSite=Lax至少可以强制使用。

app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Lax });
Run Code Online (Sandbox Code Playgroud)