Vac*_*ano 11 oauth-2.0 openid-connect asp.net-core refresh-token asp.net-core-3.1
我已经添加AddOpenIdConnect
到ConfigureServices
我的 ASP.NET Core 3.1 Razor 应用程序的方法中。在令牌过期之前,它运行良好,然后我从 IDP 收到 401 响应。
我看过一个例子,展示了一种手动连接刷新令牌的方法。
但我很犹豫要不要这样做。微软的人似乎不太可能没有考虑刷新令牌。
ASP.NET Core 3.1 是否有办法让刷新令牌自动更新访问令牌?
Vac*_*ano 18
这是我想出的。由于我找不到很多关于如何在 ASP.NET Core 中使用 cookie 刷新令牌的示例,我想我会在这里发布。(我在问题中链接到的那个有问题。)
这只是我尝试让这个工作。它尚未用于任何生产环境。此代码在ConfigureServices
方法中。
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.Events = new CookieAuthenticationEvents
{
// After the auth cookie has been validated, this event is called.
// In it we see if the access token is close to expiring. If it is
// then we use the refresh token to get a new access token and save them.
// If the refresh token does not work for some reason then we redirect to
// the login screen.
OnValidatePrincipal = async cookieCtx =>
{
var now = DateTimeOffset.UtcNow;
var expiresAt = cookieCtx.Properties.GetTokenValue("expires_at");
var accessTokenExpiration = DateTimeOffset.Parse(expiresAt);
var timeRemaining = accessTokenExpiration.Subtract(now);
// TODO: Get this from configuration with a fall back value.
var refreshThresholdMinutes = 5;
var refreshThreshold = TimeSpan.FromMinutes(refreshThresholdMinutes);
if (timeRemaining < refreshThreshold)
{
var refreshToken = cookieCtx.Properties.GetTokenValue("refresh_token");
// TODO: Get this HttpClient from a factory
var response = await new HttpClient().RequestRefreshTokenAsync(new RefreshTokenRequest
{
Address = tokenUrl,
ClientId = clientId,
ClientSecret = clientSecret,
RefreshToken = refreshToken
});
if (!response.IsError)
{
var expiresInSeconds = response.ExpiresIn;
var updatedExpiresAt = DateTimeOffset.UtcNow.AddSeconds(expiresInSeconds);
cookieCtx.Properties.UpdateTokenValue("expires_at", updatedExpiresAt.ToString());
cookieCtx.Properties.UpdateTokenValue("access_token", response.AccessToken);
cookieCtx.Properties.UpdateTokenValue("refresh_token", response.RefreshToken);
// Indicate to the cookie middleware that the cookie should be remade (since we have updated it)
cookieCtx.ShouldRenew = true;
}
else
{
cookieCtx.RejectPrincipal();
await cookieCtx.HttpContext.SignOutAsync();
}
}
}
};
})
.AddOpenIdConnect(options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = oidcDiscoveryUrl;
options.ClientId = clientId;
options.ClientSecret = clientSecret;
options.RequireHttpsMetadata = true;
options.ResponseType = OidcConstants.ResponseTypes.Code;
options.UsePkce = true;
// This scope allows us to get roles in the service.
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("offline_access");
// This aligns the life of the cookie with the life of the token.
// Note this is not the actual expiration of the cookie as seen by the browser.
// It is an internal value stored in "expires_at".
options.UseTokenLifetime = false;
options.SaveTokens = true;
});
Run Code Online (Sandbox Code Playgroud)
这段代码有两部分:
AddOpenIdConnect
:这部分代码为应用程序设置OIDC。这里的关键设置是:
SignInScheme
:这让 ASP.NET Core 知道您想使用 cookie 来存储您的身份验证信息。UseTokenLifetime
:据我所知,这将 cookie 中的内部“expires_at”值设置为访问令牌的生命周期。(不是实际的 cookie 过期,它停留在会话级别。)SaveTokens
:据我所知,这就是导致令牌保存在 cookie 中的原因。OnValidatePrincipal
:当 cookie 已被验证时调用此部分。在本节中,我们检查访问令牌是否接近或已过期。如果是,则它会刷新并将更新的值存储在 cookie 中。如果令牌无法刷新,则用户将被重定向到登录屏幕。该代码使用这些必须来自您的配置文件的值:
clientId
:OAuth2 客户端 ID。也称为客户端密钥、消费者密钥等。clientSecret
:OAuth2 客户端密码。也称为消费者秘密等。oidcDiscoveryUrl
:指向您的 IDP 众所周知的配置文档的 URL 的基本部分。如果您的众所周知的配置文档在,https://youridp.domain.com/oauth2/oidcdiscovery/.well-known/openid-configuration
那么此值将是https://youridp.domain.com/oauth2/oidcdiscovery
.tokenUrl
:指向您的 IDP 令牌端点的 URL。例如:https:/youridp.domain.com/oauth2/token
refreshThresholdMinutes
:如果您等到访问令牌非常接近到期,那么您将面临依赖访问令牌的调用失败的风险。(如果距离过期还有 5 毫秒,那么在您有机会刷新它之前,它可能会过期并导致调用失败。)此设置是您希望将访问令牌视为准备好刷新的过期前的分钟数。* 我是 ASP.NET Core 的新手。因此,我不能 100% 确定这些设置是否符合我的想法。这只是一些对我有用的代码,我想我会分享它。它可能适合您,也可能不适合您。
归档时间: |
|
查看次数: |
4919 次 |
最近记录: |