C# 静默刷新在飞行前选项上进行身份验证,但在获取用户信息端点时不进行身份验证
环境:C# 静默刷新在飞行前选项上进行身份验证,但在获取用户信息端点时不进行身份验证,c#,identityserver4,identityserver3,oidc-client-js,C#,Identityserver4,Identityserver3,Oidc Client Js,环境: 支持隐式流的实例 Angular 7客户端应用程序使用 使用ASP.NET Framework Web API资源 基本的令牌发布和验证在我们的环境中运行良好。我现在尝试启用静默刷新技术(as)。在启用了自动Lentrenew和一个短的AccessTokenLifetime之后,我可以看到无声请求在我的浏览器控制台中如我所期望的那样发出 我可以看到对IS4的UserInfo端点的两个后续调用(参见下面的屏幕截图)。第一个是CORS飞行前选项请求。在我的IProfileService.
- 支持隐式流的实例
- Angular 7客户端应用程序使用
- 使用ASP.NET Framework Web API资源
自动Lentrenew
和一个短的AccessTokenLifetime
之后,我可以看到无声请求在我的浏览器控制台中如我所期望的那样发出
我可以看到对IS4的UserInfo端点的两个后续调用(参见下面的屏幕截图)。第一个是CORS飞行前选项
请求。在我的IProfileService.IsActiveAsync()
的自定义实现中的断点处,我可以看到此请求已成功进行身份验证(通过检查httpContext
)
但是,对UserInfo端点的第二个请求(GET
)没有进行身份验证。IProfileService.IsActiveAsync()
中的断点显示没有经过身份验证的用户,因此我用于验证用户是否处于活动状态(调用另一个API)的例程返回false,该值将转换为401。我可以在失败的GET
请求WWW-Authenticate:error=“invalid_-token”
上看到此标题
我尝试指定一个IdentityTokenLifetime
小于AccessTokenLifetime
per的IdentityTokenLifetime,但没有成功
以下是两个请求的日志:
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/connect/userinfo
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 8.5635ms 204
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/connect/userinfo
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
IdentityServer4.Hosting.IdentityServerMiddleware:Information: Invoking IdentityServer endpoint: IdentityServer4.Endpoints.UserInfoEndpoint for /connect/userinfo
IdentityServer4.Validation.TokenValidator:Error: User marked as not active: f84db3aa-57b8-48e4-9b59-6deee3d288ad
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 94.7189ms 401
问题:
在静默刷新过程中,如何获取对UserInfo端点的get
请求,以在HttpContext
中进行身份验证
更新:
添加两个请求的所有标题的屏幕截图以及由此产生的浏览器cookies,以调查@Anders的答案
对/connect/userinfo
的请求由IdentityServer域/路径中的会话身份验证cookie进行身份验证
我的猜测是cookie正确地包含在OPTIONS请求中,而不是后续的GET请求中。通过查看请求,您可以在浏览器开发工具中验证这一点
如果我的猜测是正确的,那么原因可能是samesite属性。默认情况下,ASP.NET Core(IdentityServer4使用)中的所有身份验证Cookie都具有samesite属性,以防止跨站点请求伪造攻击
根据协议,AJAX Get请求中不允许使用samesite=lax的cookie。但是,如果选项请求中允许,我找不到任何内容。您可以验证(使用浏览器开发工具)从第一个请求到/connect/authorize
的响应中的cookie头中是否存在samesite设置
设置本身位于调用AddCookie()
的Cookie选项的Cookie
部分。MS文档说它默认为lax
另一方面,在Idsrv4 repo中有一条消息称,他们已将Idsrv4会话cookie的默认值更改为“无”
很明显,我在这里猜测了一点,但是验证我的假设应该相当简单。好的,所以我想我对发生的事情有了一个想法。您发出静默刷新令牌请求(从重定向到oidc silent refresh.html的过程中我可以看到该请求成功),并调用第一个ProfileService的“IsActiveAsync”(因为它需要通过配置文件服务为静默刷新生成令牌)。您能够看到“HttpContext.User”,因为打开了一个iframe,允许发送所有必要的cookie
用户信息飞行前请求甚至没有发送到ProfileService,因为您可以从只显示一次“调用IdentityServer端点:IdentityServer 4.Endpoints.UserInfoEndpoint for/connect/userinfo”的日志中看到这一点。此外,UserInfoEndpoint阻止任何选项请求通过(您可以在“ProcessAsync”方法的开头验证为true)
现在,当您发出实际的用户信息请求时,您正试图从HttpContext(通常使用来自cookie的信息填充)获取信息,但由于请求中没有发送cookie,因此无法访问。请求是在“getJson”方法(来自oidc客户端js库)中发出的,您可以看到请求中没有发送cookie(如果请求中有cookie,“withCredentials”属性将设置为true)
那么,我们如何获得有关用户的必要信息呢?要获取此信息,我们可以引用传递到ProfileService的“IsActiveAsync”中的“”,其中包含由访问令牌声明填充的主体(此过程可以在“ValidateAccessTokenAsync”方法中看到)。。还在仔细分析你的建议。刚才在问题的末尾添加了两个请求的屏幕截图。嗯,使用Fiddler,我看到“此请求没有发送任何cookie数据。”对于两个请求,都是对UserInfo端点的请求。我在idsrv.session
cookie中也没有看到SameSite
的值(请参见问题中cookie的最后一个屏幕截图)。还有其他想法吗?谢谢。我知道没有相同的价值。但是cookie应该作为头包含在两个请求中。。。我在这里迷路了。你用什么图书馆来申请?您确定正在发送任何与Cookie相关的选项吗?选项请求通常由浏览器发出,而不受API调用的任何帮助(或影响),因此,即使选项请求中有标题,也不意味着我们将在后续请求中使用标题发送请求。关于你的第二个问题,我真的不确定,但会调查的。谢谢,就是这样。谢谢
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/connect/userinfo
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 8.5635ms 204
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/connect/userinfo
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
IdentityServer4.Hosting.IdentityServerMiddleware:Information: Invoking IdentityServer endpoint: IdentityServer4.Endpoints.UserInfoEndpoint for /connect/userinfo
IdentityServer4.Validation.TokenValidator:Error: User marked as not active: f84db3aa-57b8-48e4-9b59-6deee3d288ad
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 94.7189ms 401