c# - 静默刷新在 OPTIONS 预检上进行身份验证,但不在 GET 到 UserInfo 端点上进行身份验证

标签 c# identityserver4 identityserver3 oidc-client-js

环境:

基本 token 发行和验证在我们的环境中运行良好。我现在正在尝试启用静默刷新技术(如 documented here )。在启用 automaticSilentRenew 和一个简短的 AccessTokenLifetime 之后,我可以在我的浏览器控制台中看到静默请求,正如我所期望的那样。

我可以看到对 IS4 的 UserInfo 端点的两次后续调用(请参见下面的屏幕截图)。第一个是 CORS 预检 OPTIONS 请求。在我的 IProfileService.IsActiveAsync() 自定义实现的断点处,我可以看到此请求已成功通过身份验证(通过检查 httpContext)。

enter image description here

public class ProfileService : IProfileService
{
    private readonly HttpContext _httpContext;

    public ProfileService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContext = httpContextAccessor.HttpContext;
    }

    ...

    public async Task IsActiveAsync(IsActiveContext context)
    {
        var temp = _httpContext.User; // breakpoint here
        // call external API with _httpContext.User info to get isActive
    }
}

但是,对 UserInfo 端点的第二个请求 (GET) 未进行身份验证。我在 IProfileService.IsActiveAsync() 中的断点显示没有经过身份验证的用户,因此我验证用户是否处于事件状态(调用另一个 API)的例程返回 false,它被转换为 401。我可以看到这个失败的 GET 请求的 header WWW-Authenticate: error="invalid_token"

我已尝试根据 this 指定小于 AccessTokenLifetimeIdentityTokenLifetime没有成功。

这是两个请求的日志:

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 进行身份验证?

更新:

添加两个请求的所有 header 的屏幕截图和生成的浏览器 cookie 以调查@Anders 的答案。

<code>OPTIONS</code> request to UserInfo endpoint <code>GET</code> request to UserInfo endpoint resulting cookies in browser

最佳答案

好吧,我想我知道发生了什么。您发出静默刷新 token 请求(从我从重定向到 oidc-silent-refresh.html 中看到的内容成功)并且调用第一个 ProfileService 的“IsActiveAsync”(因为它需要通过配置文件服务来生成 token 静默刷新)。您能够看到“HttpContext.User”,因为打开了一个允许发送所有必要 cookie 的 iframe。

用户信息预检请求甚至没有到达配置文件服务,正如您从日志中看到的那样,仅显示一次“调用 IdentityServer 端点:IdentityServer4.Endpoints.UserInfoEndpoint for/connect/userinfo”。此外,UserInfoEndpoint 会阻止任何选项请求通过(您可以在“ProcessAsync”方法的开头验证它是否为真 here)。

现在,当您发出实际的用户信息请求时,您正试图从 HttpContext 获取信息(通常使用来自 cookie 的信息填充),但它是不可访问的,因为请求中没有发送 cookie。提出要求here在“getJson”方法(来自 oidc-client-js 库)中,您可以看到请求中没有发送任何 cookie(如果是,“withCredentials”属性将在请求中设置为 true)。

那么我们如何获取用户的必要信息呢?要获取此信息,我们可以引用“context” ' 传递到 ProfileService 的“IsActiveAsync”,其中包含由访问 token 声明填充的主体(此过程可以在“ValidateAccessTokenAsync”方法中看到 here)。

关于c# - 静默刷新在 OPTIONS 预检上进行身份验证,但不在 GET 到 UserInfo 端点上进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54775582/

相关文章:

identityserver4 - IdentitySever4 用户声明和 ASP.NET User.Identity

asp.net - 使用 Identity Server 3,ClaimsPrinciple 即使在不记名 token 身份验证成功后仍为空

c# - 将 ListView 中的 SelectedItems 绑定(bind)到 Windows Phone 8.1 中的 ViewModel

c# - Xamarin Forms MVVM更新不适用于UWP

asp.net-core - Identityserver4中的函数IntrospectionClient总是返回Unauthorized

oauth-2.0 - 使用 Identity Server 4 在 Web API 2 Framework 4.x 中进行访问 token 验证

oauth-2.0 - auth0 和 IdentityServer 有什么不同?

angular - oidc-client-js 中的静默更新不起作用

c# - Blazor RenderFragment 到字符串

c# - 无法使用 C# 从 API 获取 json 响应