如何使用OpenId Connect的刷新令牌在asp.net核心中处理过期的访问令牌

lon*_*day 12 cookies openid-connect aspnet-contrib asp.net-core

我已使用和使用"Microsoft.AspNetCore.Authentication.OpenIdConnect":"1.0.0和"Microsoft.AspNetCore.Authentication.Cookies":"1.0.0"的asp.net核心mvc应用程序配置了ASOS OpenIdConnect服务器.我已经测试了"授权代码"工作流程,一切正常.

客户端Web应用程序按预期处理身份验证,并创建一个存储id_token,access_token和refresh_token的cookie.

如何强制Microsoft.AspNetCore.Authentication.OpenIdConnect在过期时请求新的access_token?

asp.net核心mvc应用程序忽略过期的access_token.

我想让openidconnect看到过期的access_token然后使用刷新令牌进行调用以获得新的access_token.它还应该更新cookie值.如果刷新令牌请求失败,我希望openidconnect"注销"cookie(删除它或其他东西).

app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            AuthenticationScheme = "Cookies"
        });

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            ClientId = "myClient",
            ClientSecret = "secret_secret_secret",
            PostLogoutRedirectUri = "http://localhost:27933/",
            RequireHttpsMetadata = false,
            GetClaimsFromUserInfoEndpoint = true,
            SaveTokens = true,
            ResponseType = OpenIdConnectResponseType.Code,
            AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet,
            Authority = http://localhost:27933,
            MetadataAddress = "http://localhost:27933/connect/config",
            Scope = { "email", "roles", "offline_access" },
        });
Run Code Online (Sandbox Code Playgroud)

lon*_*day 16

似乎在openidconnect身份验证中没有编程用于asp.net核心在收到后管理服务器上的access_token.

我发现我可以拦截cookie验证事件并检查访问令牌是否已过期.如果是,请使用grant_type = refresh_token对令牌端点进行手动HTTP调用.

通过调用context.ShouldRenew = true; 这将导致cookie更新并在响应中发送回客户端.

我已经提供了我所做的基础,并且一旦所有工作都得到解决,我将努力更新这个答案.

app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            AuthenticationScheme = "Cookies",
            ExpireTimeSpan = new TimeSpan(0, 0, 20),
            SlidingExpiration = false,
            CookieName = "WebAuth",
            Events = new CookieAuthenticationEvents()
            {
                OnValidatePrincipal = context =>
                {
                    if (context.Properties.Items.ContainsKey(".Token.expires_at"))
                    {
                        var expire = DateTime.Parse(context.Properties.Items[".Token.expires_at"]);
                        if (expire > DateTime.Now) //TODO:change to check expires in next 5 mintues.
                        {
                            logger.Warn($"Access token has expired, user: {context.HttpContext.User.Identity.Name}");

                            //TODO: send refresh token to ASOS. Update tokens in context.Properties.Items
                            //context.Properties.Items["Token.access_token"] = newToken;
                            context.ShouldRenew = true;
                        }
                    }
                    return Task.FromResult(0);
                }
            }
        });
Run Code Online (Sandbox Code Playgroud)

  • 你真的应该在OnValidatePrincipal中返回一个返回Task.FromResult(0)吗?为什么?并且可以使用Task.CompletedTask吗? (2认同)
  • 应该是`expire <DateTime.Now`.此外,如果支持,可以使用`Task.CompletedTask`. (2认同)