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资源
基本的令牌发布和验证在我们的环境中运行良好。我现在尝试启用静默刷新技术(as)。在启用了
自动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